Binary adder problem

L

LaVic

Hello Everyone,

I am trying to add two binary numbers in the form of two arrays. The
code that i have been using compiles, but it does not give me the
results i would expect. The problem that i am having is that it does
not carry ones over to the next significant digit if i have a 1 + 1 =
10 case. Could anyone help me by giving an explanation in the form of a
correction if possible. I would appreciate any feedback. Thank You !

Here is the code

// Binary number manipulation

#include
#include
#include
//#include

main()
{

int array_value1[ 4 ] = { 0, 0, 1, 1 }; //4 element array

int array_value2[ 4 ] = { 0, 1, 0, 1 }; //4 element array

int array_value3[4];

int i;


for( i = 0; i <4; i++)
// printf("d[%i] = %i \n", i, array_value1 );

for( i= 0; i <4; i++)
// printf("d[%i] = %i \n", i, array_value2);

for (i=0; i <4; i++)
{
array_value3 = array_value1 + array_value2;

if ( (array_value1== 1) && (array_value2== 1))
{

array_value3 = 0;
array_value3[i+1] = 1 + array_value1[i+1] + array_value2[i+1];

}

}
for( i= 0; i <4; ++i)
printf("d[%i] = %i \n", i, array_value3);

return(0);
}
 
G

Guest

Hi,
I am trying to add two binary numbers in the form of two arrays. The
code that i have been using compiles, but it does not give me the
results i would expect. The problem that i am having is that it does
not carry ones over to the next significant digit if i have a 1 + 1 =
10 case. Could anyone help me by giving an explanation in the form of a
correction if possible. I would appreciate any feedback. Thank You !

Here is the code

// Binary number manipulation

#include
#include
#include
//#include

main()
{

int array_value1[ 4 ] = { 0, 0, 1, 1 }; //4 element array

int array_value2[ 4 ] = { 0, 1, 0, 1 }; //4 element array

int array_value3[4];

int i;


for( i = 0; i <4; i++)
// printf("d[%i] = %i \n", i, array_value1 );

for( i= 0; i <4; i++)
// printf("d[%i] = %i \n", i, array_value2);

for (i=0; i <4; i++)
{
array_value3 = array_value1 + array_value2;

if ( (array_value1== 1) && (array_value2== 1))
{

array_value3 = 0;


your code doesn't care if there was a carry in the previous loop cycle.
array_value3 contains the carry of the previous iteration. if you
overwrite it,it is gone.
you could solve this by using a separate carry flag and using it properly.
array_value3[i+1] = 1 + array_value1[i+1] + array_value2[i+1];

this is dangerous. array_value3[i+1] will adress an element out of bounds if
there is an overflow in the final iteration.
again, you can solve this by using a separate carry flag to signal an
overflow.
}

}
for( i= 0; i <4; ++i)
printf("d[%i] = %i \n", i, array_value3);

return(0);
}


--

Kind regards,
Bruno.
(e-mail address removed)
Remove only "_nos_pam"
 
L

lfinsto1

LaVic said:
I am trying to add two binary numbers in the form of two arrays.

This seems like an awful waste. The following is a little example of
how to do it using bit-wise operations on unsigned ints. The program
adds two positive integers. It could be refined in a lot of ways. It
seems to work correctly, but no guarantees. I tried to get it to show
that overflow occurred if the sum went out of range, but it doesn't
work, and I don't have time to work on it anymore. I hope you find it
helpful.

Laurence Finston

**************************************

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{

char c[8];

unsigned int mask = 1;
unsigned long carry_mask = 1; /* Wasting 31 bits here, but what the
heck. */

unsigned int operand_1 = 0;
unsigned int operand_2 = 0;
unsigned int result = 0;

unsigned short uint_size = sizeof(unsigned int) * 8; /* Assume 8
bits per byte
(a pretty
safe assumption). */

unsigned short curr_pos = 0;

while (true)
{

mask = 1;
carry_mask = 0;
result = 0;

#if 0
unsigned int max_mask = ~carry_mask;
cout << "max_mask == " << max_mask << endl;
#endif

cout << "Enter operand 1: ";
cin >> operand_1;

cout << "Enter operand 2: ";
cin >> operand_2;

for (curr_pos = 0; curr_pos < uint_size; ++curr_pos)
{

cout << "At beginning of loop:\n"
<< "curr_pos == " << curr_pos
<< endl
<< "mask == " << mask
<< endl
<< "carry_mask == " << carry_mask
<< endl;

if (mask & carry_mask & operand_1 & operand_2)
{
carry_mask <<= 1;
result |= mask;
}

else if (mask & carry_mask & (operand_1 | operand_2))
{
carry_mask <<=1;
}

else if (mask & carry_mask)
{
carry_mask = 0;
result |= mask;

}

else if (mask & ~carry_mask & operand_1 & operand_2)
{
carry_mask = mask << 1;

}
else if (mask & ~carry_mask & (operand_1 | operand_2))
{
carry_mask = 0;
result |= mask;
}

cout << "At end of loop:"
<< endl
<< "result == " << result << endl
<< "carry_mask == " << carry_mask
<< endl
<< "***************"
<< endl << endl;

mask <<= 1;

} /* |for| */

cout << "result == " << result << endl << endl;
cout << "carry_mask == " << carry_mask << endl;

/* This doesn't work. Don't have time to play with it anymore.
*/

if (carry_mask)
cout << "Overflow occurred.";
else
cout << "No overflow occurred.";

cout << "Enter `x' to quit, or any other character to continue:
";

cin >> c;

if (!strcmp(c, "x"))
break;

} /* |while (true)| */

return 0;
}
 
L

lfinsto1

(e-mail address removed) schrieb:

Of course, all of the cases where `mask' and `carry_mask' are both
non-null have been accounted for, so ` & ~carry_mask' isn't needed.
else if (mask & ~carry_mask & operand_1 & operand_2)
{
carry_mask = mask << 1;

}
else if (mask & ~carry_mask & (operand_1 | operand_2))
{
carry_mask = 0;
result |= mask;
}

Laurence Finston
 
L

lfinsto1

Here's a corrected version. I was assuming that `unsigned long' was
larger than `unsigned int'. This is not the case. It's possible to
keep track of possible overflow by shifting `carry_mask' at the
beginning of the loop. This way, the 1 in the left column, if present,
isn't shifted off the end during the final iteration.

Laurence Finston


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{

char c[8];

unsigned int mask = 1;
unsigned int carry_mask = 0;

unsigned int operand_1 = 0;
unsigned int operand_2 = 0;
unsigned int result = 0;

unsigned short uint_size = sizeof(unsigned int) * 8; /* Assume 8
bits per byte
(a pretty
safe assumption). */

while (true)
{

mask = 1;
carry_mask = 0;
result = 0;

#if 0

/* There's no need to calculate `max_mask', since it's the same
as the constant `UINT_MAX'. */

unsigned int max_mask = ~carry_mask;
cout << "max_mask == " << max_mask << endl
<< "UINT_MAX == " << UINT_MAX << endl;
// 4294967295

#endif

cout << "Enter operand 1: ";
cin >> operand_1;

cout << "Enter operand 2: ";
cin >> operand_2;

unsigned short curr_pos = 0;

for (curr_pos = 0; curr_pos < uint_size; ++curr_pos)
{

carry_mask <<= 1;

cout << "At beginning of loop:\n"
<< "curr_pos == " << curr_pos
<< endl
<< "mask == " << mask
<< endl
<< "carry_mask == " << carry_mask
<< endl;

if (mask & carry_mask & operand_1 & operand_2)
{
result |= mask;

}

else if (mask & carry_mask & (operand_1 | operand_2))
{

// Do nothing.
}

else if (mask & carry_mask)
{
carry_mask = 0;
result |= mask;
}

else if (mask & ~carry_mask & operand_1 & operand_2)
{
carry_mask = mask;
}
else if (mask & ~carry_mask & (operand_1 | operand_2))
{
carry_mask = 0;
result |= mask;
}

cout << "At end of loop:"
<< endl
<< "result == " << result << endl
<< "carry_mask == " << carry_mask
<< endl
<< "***************"
<< endl << endl;

mask <<= 1;

} /* |for| */

cout << "result == " << result << endl << endl;

cout << "carry_mask == " << carry_mask << endl;

if (carry_mask)
cout << "Overflow occurred." << endl;
else
cout << "No overflow occurred." << endl;


cout << "Enter `x' to quit, or any other character to continue:
";

cin >> c;

if (!strcmp(c, "x"))
break;

} /* |while (true)| */

return 0;
}
 
L

lfinsto1

Just for the sake of completeness, here's the same code, but with the
redundant
"& ~carry_mask" conditions removed.

Laurence Finston


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{

char c[8];

unsigned int mask = 1;
unsigned int carry_mask = 0;

unsigned int operand_1 = 0;
unsigned int operand_2 = 0;
unsigned int result = 0;

unsigned short uint_size = sizeof(unsigned int) * 8; /* Assume 8
bits per byte
(a pretty
safe assumption). */

while (true)
{

mask = 1;
carry_mask = 0;
result = 0;

#if 1
unsigned int max_mask = ~carry_mask;
cout << "max_mask == " << max_mask << endl
<< "UINT_MAX == " << UINT_MAX << endl;
// 4294967295

#endif

cout << "Enter operand 1: ";
cin >> operand_1;

cout << "Enter operand 2: ";
cin >> operand_2;

unsigned short curr_pos = 0;

for (curr_pos = 0; curr_pos < uint_size; ++curr_pos)
{

carry_mask <<= 1;

cout << "At beginning of loop:\n"
<< "curr_pos == " << curr_pos
<< endl
<< "mask == " << mask
<< endl
<< "carry_mask == " << carry_mask
<< endl;

if (mask & carry_mask & operand_1 & operand_2)
{
result |= mask;

}

else if (mask & carry_mask & (operand_1 | operand_2))
{

// Do nothing.
}

else if (mask & carry_mask)
{
carry_mask = 0;
result |= mask;
}

else if (mask & operand_1 & operand_2)
{
carry_mask = mask;
}
else if (mask & (operand_1 | operand_2))
{
carry_mask = 0;
result |= mask;
}

cout << "At end of loop:"
<< endl
<< "result == " << result << endl
<< "carry_mask == " << carry_mask
<< endl
<< "***************"
<< endl << endl;

mask <<= 1;

} /* |for| */

cout << "result == " << result << endl << endl;
cout << "carry_mask == " << carry_mask << endl;

if (carry_mask)
cout << "Overflow occurred." << endl;
else
cout << "No overflow occurred." << endl;


cout << "Enter `x' to quit, or any other character to continue:
";

cin >> c;

if (!strcmp(c, "x"))
break;

} /* |while (true)| */

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top