I have a vector of structs containing the following type of variables:
Date Time Low
11/1/17 929 74.25
11/1/17 930 73
11/1/17 931 75
11/1/17 932 70
etc.
I now want to add another struct to my vector called "LowRun", where LowRun is the smallest low at every point in the iteration, like so:
Date Time Low LowRun
11/1/17 929 74.25 74.25
11/1/17 930 73 73
11/1/17 931 75 73
11/1/17 932 70 70
This is what I've tried so far, but this is not giving the right output:
edited:
int CalcLow_SoFar(std::vector<PriceInfo>& p)
double running_low = p[0].Low;
for (size_t i = 1; i < p.size(); ++i)
{
if (p[i].Time > 929
&& p[i].Time < 1601
&& p[i].Date == p[i - 1].Date)
{
if (p[i].Low < running_low)
{
running_low = p[i].Low;
p[i].LowRun = running_low;
}
}
}
return 0;
}
Can you help me get unstuck, thank you!
You've got several weird logic problems in your code, so I'm just going to list them here.
This if statement makes no sense: if (p[i].Low < p[i-1].Low). You assign running_low to the current value whenever the current value is less than the previous value. However, it's perfectly possible for the value to decrease while not being lower than the running low. For example, if you have the sequence 1, 3, 2, the LowRun value at the index 2 gets assigned to 2 because 2 is less than 3, even though the running low should be 1.
The if statement after the one I was talking about (if (p[i+1].Low < running_low)) would have been good if you didn't add 1 to i for some reason. Instead of going from 1 to p.size() - 1, you're now going from 2 to p.size(), so you access one element past the end of the vector which is undefined behavior.
You only assigned the LowRun values when the running_low value changes. This means that if a value didn't change the running low, it's LowRun value is uninitialized which is where the garbage values come from.
You didn't initialize running_low to the first element.
I don't know the details of what you're doing, but the condition checking the time and date looks suspicious, so I've removed it for now. It basically ignores an entry if it's the first one on that day. If that's what you want to do, instead of initializing running_low to the value of the first element, initialize it to something like std::numeric_limits<double>::max() so it's guaranteed to get updated on the first valid entry and change your loop to start from 0.
This doesn't affect the functionality, but unlike main(), other functions you define don't have to return an int or even anything at all. Use void if you don't need the function to return anything.
Lastly, you should get in the habit of using good formatting including proper indents so you don't confuse yourself.
The fixed code:
void CalcLow_SoFar(std::vector<PriceInfo>& p)
{
double running_low = p[0].Low;
p[0].LowRun = p[0].Low;
for (size_t i = 1; i < p.size(); ++i)
{
if (p[i].Low < running_low)
{
running_low = p[i].Low;
}
p[i].LowRun = running_low;
}
}
Version with the date and time checks:
void CalcLow_SoFar(std::vector<PriceInfo>& p)
{
double running_low = std::numeric_limits<double>::max();
for (size_t i = 0; i < p.size(); ++i)
{
if (p[i].Time > 929
&& p[i].Time < 1601
&& i != 0
&& p[i].Date == p[i - 1].Date
&& p[i].Low < running_low)
{
running_low = p[i].Low;
}
p[i].LowRun = running_low;
}
}
Note that for this version, the Low values for the first few elements will be a very large value since a valid entry hasn't been encountered and running_low still holds the value we initialized it to.
Here's the version which only includes the values from the same day in the running low and also ignores any values with a time not in [930, 1600]:
void CalcLow_SoFar(std::vector<PriceInfo>& p)
{
double running_low;
for (size_t i = 0; i < p.size(); ++i)
{
if (i == 0 || p[i].Date != p[i - 1].Date)
{
running_low = std::numeric_limits<double>::max();
}
if (p[i].Time >= 930
&& p[i].Time <= 1600
&& p[i].Low < running_low)
{
running_low = p[i].Low;
}
p[i].LowRun = running_low;
}
}
Similar to the second version in this answer, the LowRun values might be std::numeric_limits<double>::max() if a value in that day within the time limits hasn't been encountered yet.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 months ago.
Improve this question
I have tried to come up with a solution to the n-queen problem, through backtracking. I have created a board, and I think I have created functions which checks whether a piece can be placed at position column2 or not, in comparison to a piece at position column1. And I guess I somehow want to loop through the columns, to check if the current piece is in a forbidden position to any of the power pieces already placed at the first row through the current minus one. I haven't done this yet, but I'm just confused at the moment, so I can't really see how I should do it.
Let me share the code I have written so far
// Method for creating chessboard
vector<vector<vector<int>>> create_chessboard(int size_of_board)
{
vector<int> v1;
vector<vector<int>> v2;
vector<vector<vector<int>>> v3;
for (int i = 0; i < size_of_board; i++)
{
for (int j = 0; j < size_of_board; j++)
{
v1.clear();
v1.push_back(i);
v1.push_back(j);
v2.push_back(v1);
}
v3.push_back(v2);
v2.clear();
}
return v3;
}
// Method for visualizing chessboard
void visualize_board(vector<vector<vector<int>>> chess, int dimension_of_board)
{
int i = 1;
for (vector<vector<int>> rows : chess)
{
for (int j = 0; j < dimension_of_board; j++)
{
cout << "(" << rows[j][0] << "," << rows[j][1] << ")" << " ";
}
cout << endl;
}
}
// Method for checking if two coordinates are on the same diagonal
bool check_diagonal(vector<int> coordinate1, vector<int> coordinate2)
{
if(abs(coordinate1[1] - coordinate2[1]) == abs(coordinate1[0] - coordinate2[0]))
{
return true;
}
return false;
}
bool check_column(vector<int> coordinate1, vector<int> coordinate2)
{
if(coordinate1[1] == coordinate2[1])
{
return true;
}
return false;
}
bool check_row(vector<int> coordinate1, vector<int> coordinate2)
{
if (coordinate1[0] == coordinate2[0])
{
return true;
}
return false;
}
bool check_allowed_positions(vector<int> coordinate1, vector<int> coordinate2, int column)
{
if (check_diagonal(coordinate1, coordinate2))
{
return false;
}
if (check_column(coordinate1, coordinate2))
{
return false;
}
if (check_row(coordinate1, coordinate2))
{
return false;
}
return true;
}
vector<vector<int>> solve_nqueen(vector<vector<vector<int>>> board, int dimension_of_board, int row)
{
vector<int> first_element = board[0][0];
vector<vector<int>> solution_space;
if (dimension_of_board == row)
{
cout << "we found a solution!";
}
/*
if (dimension_of_board == row)
{
}
for (int j = 0; j < dimension_of_board; j++)
{
if (check_allowed_positions(board, row, j))
{
do something here
solve_nqueen(board, dimension_of_board, row+1);
}
else
{
do something here;
}
}
return;
*/
return solution_space;
}
I would be really happy if someone could just lay up a few steps I have to take in order to build the solve_nqueen function, and maybe some remarks on how I could do that. If I should complement with some further information, just let me know! I'm happy to elaborate.
I hope this isn't a stupid question, but I have been trying to search the internet for a solution. But I didn't manage to use what I found.
Best wishes,
Joel
There is not always a solution, like e.g. not for 2 queens on 2x2 board, or for 3 queens on a 3x3 board.
This is a well-known problem (which can also be found in the internet). According to this, there is not a simple rule or structure, how you can find a solution. In fact, you could reduce the problem by symmetries, but that is not that simple, too.
Well according to this, you have to loop through all (n out of n x n) solutions, and do all tests for every queen. (In fact, reduce it to half again, by only checking a certain pair of queens, once only - but again that is not much, and such reduction takes some time, too).
Note: Your check routines are correct.
For 8 queens on a 8x8 board, write 8 nested loops from i(x)=0 to 63
(row is i(x)%8 and column is i(x)/8). You also need to check then, if a queen does not sit on queen, but your check routines will already find that. Within second nested loop, you can already check if the first two queens are okay, or otherwise, you do not have to go any deeper, but can already increment the value of first nested loop (move the second queen on a new position).
Also it would be nice, I propose not to write the search for a n-problem, but for a n=8 problem or n=7 problem. (That is easier for the beginning.).
Speed-Ups:
While going deeper into the nested loops, you might hold a quick
record (array) of positions which already did not work for upper
loops (still 64 records to check, but could be written to be faster than doing your check routines again).
Or even better, do the inner loops only through a list from remaining candidates, much less than (n x n) positions.
There should be some more options for speed-ups, which you might find.
Final proposal: do not only wait for the full result to come, but also track, when e.g. you find a valid position of 5 queens, then of 6 queens and so on - which will be more fun then (instead of waiting ages with nothing happening).
A further idea is not to loop, e.g. from 0 to 63 for each queen, but "randomly". Which also might lead to more surprising. For this, mix an array 0 .. 63 to a random order. Then, still do the loop from 0 to 63 but this is just the index to the random vector. Al right? Anyway, it would even be more interesting to create 8 random vectors, for each queen one random vector. If you run this program then, anything could happen ... the first few trials could (theoretically) already deliver a successful result.
If you would like to become super efficient, please note that the queen state on the 8x8 board can be stored in one 64-bit-integer variable (64 times '0' or '1' where '1' means here is queen. Keyword: bitboards). But I didn't mention this in the beginning, because the approach which you started is quite different.
And from that on, you could create 64 bit masks for each queen position, to each position to which a queen can go. Then you only need to do 1 "bitwise AND" operation of two (properly defined) 64-bit variables, like a & b, which replaces your (diagonal-, column-, row-) check routines by only one operation and thus is much faster.
Avoid too many function calls, or use inline.
... an endless list of possible dramatic speed-ups: compiler options, parallelization, better algorithms, avoid cache misses (work on a possibly low amount of memory or access memory in a regular way), ... as usual ...
My best answer, e.g. for 8-queen problem:
queen is between 0 .. 7
queen is between 8 .. 15
queen is between 16 .. 23
queen is between 24 .. 31
queen is between 32 .. 39
queen is between 40 .. 47
queen is between 48 .. 55
queen is between 56 .. 63
because all 8 queens have to be on different rows!
These are the limits of the nested loops then, which gives "only"
8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 = 16777216
possibilities to be checked. This can be quick on modern machines.
Then probably you don't need anything more sophisticated (to which my first answer refers - for the 8x8 queens problem.) Anyway, you could still also keep a record of which column is still free, while diving into the nested loops, which yields a further dramatic cut down of checks.
I wrote some C code (similar to C++) to verify my answer. In fact, it is very fast, much less than a second (real 0m0,004s; user 0m0,003s; sys 0m0,001s). The code finds the correct number of 92 solutions for the 8x8 queens problem.
#include <stdio.h>
int f(int a, int b)
{
int r1, c1, r2, c2, d1, d2;
int flag = 1;
r1 = a / 8;
r2 = b / 8;
c1 = a % 8;
c2 = b % 8;
d1 = r1 - r2;
d2 = c1 - c2;
if( d1 == d2 || d1 == -d2 || c1 == c2 ) flag=0;
return flag;
}
int main()
{
int p0,p1, p2, p3, p4, p5, p6, p7;
int solutions=0;
for(p0=0; p0<8; p0++)
{
for(p1=8; p1<16; p1++)
{
if( f(p0,p1) )
for(p2=16; p2<24; p2++)
{
if( f(p0,p2) && f(p1,p2) )
for(p3=24; p3<32; p3++)
{
if( f(p0,p3) && f(p1,p3) && f(p2,p3) )
for(p4=32; p4<40; p4++)
{
if( f(p0,p4) && f(p1,p4) && f(p2,p4) && f(p3,p4))
for(p5=40; p5<48; p5++)
{
if( f(p0,p5) && f(p1,p5) && f(p2,p5) && f(p3,p5) && f(p4,p5) )
for(p6=48; p6<56; p6++)
{
if( f(p0,p6) && f(p1,p6) && f(p2,p6) && f(p3,p6) && f(p4,p6) && f(p5,p6))
for(p7=56; p7<64; p7++)
{
if( f(p0,p7) && f(p1,p7) && f(p2,p7) && f(p3,p7) && f(p4,p7) && f(p5,p7) && f(p6,p7))
{
solutions++;
// 0 .. 63 integer print
printf("%2i %2i %2i %2i %2i %2i %2i %2i\n",
p0,p1,p2,p3,p4,p5,p6,p7);
// a1 .. h8 chess notation print
//printf("%c%d %c%d %c%d %c%d %c%d %c%d %c%d %c%d\n",
//p0%8+'a', p0/8+1, p1%8+'a', p1/8+1, p2%8+'a', p2/8+1, p3%8+'a', p3/8+1,
//p4%8+'a', p4/8+1, p5%8+'a', p5/8+1, p6%8+'a', p6/8+1, p7%8+'a', p7/8+1);
}
}
}
}
}
}
}
}
}
printf("%i solutions have been found\n",solutions);
return 1;
}
Notes: Subroutine f checks if two queen positions are "ok" with each other (1 means true, 0 means false, in C). An inner loop is only entered, if all already selected positions (in outer loops) are "ok" with each other.
Any idea why the else if statment will be never executed ? The value of difference is constantly changing when the program runs.
double difference = abs(reale_x[0] - reale_x[1]);
if (0 <= difference < 45) {
timer_counter += 1;
if (timer_counter == 30) {
cout << "CLICK" << '\n';
}
}
else if (difference > 50) {
timer_counter = 0;
}
That is not how comparation works in c++.
What this code
if (0 <= difference < 45) {
does is it first compares if 0 is smaller or equal to difference. It is then "replaced" by a bool value either true or false. And then a bool value (so either 1 or 0) is compared to 45. And it will always be smaller than 45. What you have there is an always true statement.
So the way you would write this if statement is
if (difference >= 0 && difference < 45){
Note that because of your else if statement it will not execute if the difference is >44 and <51
if (0 <= difference < 45) will be executed as if ((0 <= difference) < 45), which will be either 0<45 or 1<45 and will always be true. That's why the else part is not getting executed.
in mathematics, we see and write 0 <= x < 45 or something like that to define the range of the variable x. But in order to tell the computer the same thing, you have to tell more clearly. Saying, to have to tell the compiler, that the value of x is greater than or equal to zero and at the same time, that value will be less than 45, and you can tell the compiler by this statement: difference >= && difference < 45 . the && is an 'AND' operator in most of the languages.
Good morning everyone,
I have a problem where I have to calculate the shortest path (including layovers) from one train station to another. I usually don't ask for help but I am very stuck on this one. I started out by writing a standard dijkstra's algorithm and thought I could modify it for the layovers but that hasn't been the case. The program is set up as an adjacency matrix of [stationCount][stationCount] size made of edge structures. Each edge structure has an:
int departure; int arrival; int totalTime; (arrival - departure)
and all of the times are in military time (0900, 1230, etc.). The method I am having issues with is posted below and I am fairly certain my issues are with calculating/adding in the layovers. I have commented that section to mark it.
Lastly, this is the input data I am with:
1 2 0430 0600
1 4 0550 1000
2 4 0630 1100
2 5 1130 1300
3 1 1245 1500
3 6 0300 0530
4 5 0730 0945
4 7 1145 1600
4 6 1500 1900
4 3 1000 1330
5 7 1430 1730
7 6 1550 1800
I have asked the program to try to return the shortest path from (1, 6) but it is not returning the valid path. The shortest path as I have calculated it would be 1->4 (0450) + (0500) -layover + 4->6 (0400) = (1350) which I could then convert to 13 hours 10 minutes. There are multiple other paths it could take but all of them start earlier and end at the same time or later making them longer paths. If anyone has any guidance on what I am doing wrong or of a better way to do this please let me know. Thank you.
int TRAINS::dijkstra(int source, int destination)
{
vector <bool> vertexSet;
int distance[stationCount];
int minNode, minDistance, source, destination, count = 0, previousNode;
for(int i = 1; i < stationCount; ++i)
{
distance[i] = INFINITY;
vertexSet.push_back(false);
}
distance[source] = 0;
while((!empty(vertexSet)) && count < stationCount - 1)
{
count++;
minNode = INFINITY;
minDistance = INFINITY;
for(int vertex = 1; vertex < stationCount; ++vertex)
{
if(vertexSet[vertex] == false && distance[vertex] <= minDistance)
{
minDistance = distance[vertex];
minNode = vertex;
}
}
vertexSet[minNode] = true;
//so what i tried to do is that if it is the first time running through (i.e. source == minNode then it will set the distance for all verteces to .totalTime (the regular weight) and that seems to work
for(int vertex = 1; vertex < stationCount; ++vertex)
{
if(vertexSet[vertex] == false && matrix[minNode][vertex].arrival > 0)
{
if(minNode == source)
{
if(distance[minNode] != INFINITY && matrix[minNode][vertex].totalTime < distance[vertex])
{
distance[vertex] = matrix[minNode][vertex].totalTime;
if(vertex == destination)
{
return distance[vertex];
}
}
}
//then here if it wasn't the first time (this is where I am having trouble... i was trying to have it take the current departure time - the previous arrival time to calculate the layover and then add it to the current distance (distance[minNode]) plush the actual weight still... but somewhere this is going wrong and i am not getting the right output.
else
{
if(distance[minNode] != INFINITY && matrix[minNode][vertex].departure > 0 && matrix[minNode][vertex].departure - matrix[previousNode][minNode].arrival + matrix[minNode][vertex].totalTime + distance[minNode] < distance[vertex])
{
distance[vertex] = matrix[minNode][vertex].departure - matrix[previousNode][minNode].arrival + matrix[minNode][vertex].totalTime + distance[minNode];
}
if(vertex == destination)
{
return distance[vertex];
}
}
}
}
//before the next cycle i set the current minNode to previous for use in the next cycle
previousNode = minNode;
}
return -1;
}
-
My input is a range of positive integer values between 0 to 200, and I have to classify each value between ranges:0-24, 25-49, 50-74, 75-99, 100-124, 125-149, 150-174 and 175-200 and then output how many values lie is what range. The values are stored in a text file(TextScores.txt) separated with commas. Here is the code.
ifstream file;
string x;
int y,j;
int count[8]={0};
j=0;
file.open("C:\\Users\\USER\\Desktop\\TestScores.txt");
while(getline(file,x,','))
{
y = stoi(x);
if(y<=24)
{
count[0]++;
}
else
if (y>=25 && y<=49)
{
count[1]++;
}
else
if (y>=50 && y<=74)
{
count[2]++;
}
else
if (y>=75 && y<=99)
{
count[3]++;
}
else
if (y>=100 && y<=124)
{
count[4]++;
}
else
if (y>=124 && y<=149)
{
count[5]++;
}
else
if (y>=150 && y<=174)
{
count[6]++;
}
else
if (y>=175 && y<=200)
{
count[7]++;
}
}
for (int i=0; i<=7; i++)
{
cout<<"Test scores between range "<<setw(3)<<j<<" to "
<<setw(3)<<j+25<<" are "<<count[i]<<endl;
j+=25;
}
Alternatives for the hefty amount of if..else statements can be:
y<=24 ? count[0]++ : y>=25 && y<=49 ? count[1]++ : y>=50 && y<=74
count[2]++ : y>=75 && y<=99 ? count[3]++ : y>=100 && y<=124 ? count[4]++ :
y>=125 && y<=149 ? count[5]++ : y>=150 && y<=174 ? count[6]++ : count[7]++;
Or switch statements. Anyone got any other suggestions?
Note: I studied a little bit of range based for loops but I don't know precisely how to go about them in this situation. If anybody knows how to apply them on the problem specified it will be appreciated. I don't want to go into O.O.P. Thanks.
Notice that your ranges are exactly 25 apart. If you perform integer division on y, you can use that to index into your count array. There is a special case for y=200 because that would return 8, which is outside of your array size.
if (y >=0 && y < 200)
++count[y/25];
else if (y == 200)
++count[7];
As Richard Hodges states in his comment, a shorter, more idiomatic way of writing this would be just:
++count[ std::min(7, y/25) ];
You will need to include the algorithm header to access this function.
Define a struct
struct limit {
int min;
int max;
};
Then an array of that
struct limit limits[] = { {0, 24} {25, 49}, {50, 74} /* and so on */ };
Then loop over the array
while(getline(file,x,','))
{
y = stoi(x);
for (int i = 0; i < sizeof(limits)/sizeof(limits[0]); i++) {
if (y >= limits[i].min && y <= limits[i].max) {
count[i]++;
}
}
}
Of course if the pairs are equidistant the array approach doesn't make sense. Go with my proposal if you need arbitrary integer ranges.
Also note that my proposal is plain C, opposed to the STL based answer from πάντα ῥεῖ.
Besides that you can use a simple mathematical solution for your task, because there are apparently fixed steps of 25 (as was mentioned in this answer), in order to create a generic solution, you could use a std::map<std::pair<int,int>,int> that holds all the possible ranges as key values and run a loop for counting:
std::map<std::pair<int,int>,int> rangeCounts =
{ { 0, 25 }, 0 ,
{ 24, 50 }, 0 ,
{ 49, 75 }, 0 ,
// ...
{ 174, 200 }, 0 ,
};
for(std::unordered_map<std::pair<int,int>,int>::iterator it = rangeCounts.begin();
it != rangeCounts.end();
++it) {
if(y > (it->first).first && y < (it->first).second)
++(it->second);
}
As a side note: Your current range delimiters look strange because of these overlapping lower and higher limits (if else cascade or not).
and I have to classify each value between ranges:0-24, 25-49, 50-74, 75-99, 100-124, 125-149, 150-174 and 175-200 and then output how many values lie is what range.
The ranges (with my example) should look like:
std::map<std::pair<int,int>,int> rangeCounts =
{ { 0, 24 }, 0 ,
{ 25, 49 }, 0 ,
{ 50, 74 }, 0 ,
// ...
{ 175, 200 }, 0 ,
};
and the range condition
if(y >= (it->first).first && y <= (it->first).second)
Note: I studied a little bit of range based for loops but I don't know precisely how to go about them in this situation.
These have nothing to do with your range check problem. A range based for() loop just allow to iterate over a containers contents based on the std::begin() and std::end() standard functions implicitely.
So a range based for loop implementation for my sample would look like
for(auto& entry : rangeCounts) {
if(y >= entry.first.first && y =< entry.first.second)
++entry.second;
}
You have a pattern in the if..else statements. You are making constant range size of 25. So, you should use the division by 25 to find the correct case to make the increment:
while(getline(file,x,','))
{
y = stoi(x);
count[y / 25]++;
}
I am trying to implement Long Hand Multiplication method for 8 bit binary numbers stored in two arrays BeforeDecimal1 and BeforeDecimal2. The problem is I always get the wrong result. I tried to figure out the issue but couldn't do it. Here is the code:
This is a much more refined code then previous one. It is giving me result but the result is not correct.
int i=0,carry=0;
while(true)
{
if(BeforeDecimal2[i]!=0)
for(int j=7;j>=0;j--)
{
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside first, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside second, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside third, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==0)
{
cout<<"Inside fourth, j= "<<j<<endl;
carry=0;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==0)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=0;
}
}
for(int h=7;h>=0;h--)
{
if(h==0)
{
BeforeDecimal1[0]=0; // that is inserting zeros from the right
}
else
{
BeforeDecimal1[h]=BeforeDecimal1[h-1];
BeforeDecimal1[h-1]=0;
}
}
if(i==3)
break;
i++;
}
Regards
Maybe it would be easiest to back up and start with 8-bit binary numbers stored as 8-bit binary numbers. Much like when we do decimal multiplication, we start with a number of digits. We take the values of multiplying by those individual digits, and add them together to get the final result. The difference (or one obvious difference) is this since we're working in binary, all our digits represent powers of two, so we can get each intermediate result by simply bit shifting the input.
Since it's binary, we have only two possibilities for each digit: if it's a 0, then we need to add 0 times the other number shifted left the appropriate number of places. Obviously, 0 time whatever is still 0, so we simply do nothing in this case. The other possibility is that we have a 1, in which case we add 1 times the other number shifted left the appropriate number of places.
For example, let's consider something like 17 x 5, or (in binary) 10001 x 101.
10001
101
------
10001
+ 1000100
--------
= 1010101
Converting that to something more recognizable, we get 0x55, or 85d.
In code, that process comes out fairly short and simple. Start with a result of 0. Check whether the least significant bit in one operand is set. If so, add the other operand to the result. Shift the one operand right a bit and the other left a bit, and repeat until the operand you're shifting to the right equals 0:
unsigned short mul(unsigned char input1, unsigned char input2) {
unsigned short result = 0;
while (input2 != 0) {
if (input2 & 1)
result += input1;
input1 <<= 1;
input2 >>= 1;
}
return result;
}
If you want to deal with signed numbers, it's generally easiest to figure up the sign of the result separately, and do the multiplication on the absolute values.
You have problem in following lines of code
if(reverse==0)
{
totalReverse=totalReverse-1;
reverse=totalReverse;
}
after some iterations of the inner for loop (index j based) the values of reverse goes should goes to negative and when reverse less than 3 then there should be exception thrown.
Are you running this code without exception handling?
to me this smells like shift and add. is there a requirement that you may use operations simulating logical gates only?
for your full adder you have 3 inputs s(s[j]), b(BeforeDecimal1[j]), c(carry), and two outputs ns(new s[j]), nc (new carry)
the table looks like this
s b c ns nc
0 0 0 0 0 handled in v5 clause 4
0 0 1 1 0 handled in v5 clause 3
0 1 0 1 0 handled in v6 clause 5
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1 handled in v5 clause 2
1 1 0 0 1 handled in v5 clause 1
1 1 1 1 1
your code covers only 4 (now 5) of these 8 clauses
to avoid the ugly if-else-if rake i recommend to use temporary result variables (carry and s still valid in the next if clause)
when you analyze the table you could also do (pseudo bool notation)
nc = s && b || s && c || b && c;
ns = s XOR b XOR c; // there is no XOR in C++: axb = a&&!b || !a&&b
arithmetic notation
nc = (s + b + c) / 2;
ns = (s + b + c) % 2;
// [...]
for(int j=7;j>=0;j--)
{
// start changed code
const int sum = s[j] + BeforeDecimal1[j] + carry;
s[j]=sum % 2;
carry=sum / 2;
// end changed code
}
// [...]
here is a nice simulation of your problem Sequential Multiplication
Unless your requirement precisely states otherwise, which isn't clear from your question or any of your comments so far, it is not necessary to process arrays of bits. Arrays of bytes are much more efficient in both space and time.
You don't need this exhaustive explosion of cases either. The only special case is where either operand is zero, i.e. a[i]|b[i] == 0, when
result[i] = carry;
carry = 0;
All other cases can be handled by:
result[i] = a[i]*b[i]+carry;
carry = (result[i] >>> 8) & 1;
result[i] &= 0xff;
I don't see much point in the names BeforeDecimal1 and BeforeDecimal2 either.