I have this function and everything works until a and b both equal 1. When that happens the carry bit is going to 2 when its supposed to be only 0 or 1. Is my algorithm wrong for the carry bit
carry_bits |= ((a & mask) & (b & mask)) << 1u;

bool add7bits( unsigned int a, unsigned int b, unsigned int *carry_out, unsigned int     *overflow_out, unsigned int *sum_out)
{
if ( a > ( ( 1u << NUM_BITS ) - 1 ) )
{
    cout << "a value: " << a << " is too large" << endl;
    return false;
}
else if ( b > ( ( 1u << NUM_BITS ) - 1 ) )
{
    cout << "b value: " << b << " is too large" << endl;
    return false;
}
else
{
    unsigned int sum_bits = 0;
    unsigned int carry_bits = 0;
    // Use a mask to access the specific bits of interest
    unsigned int mask = 1u;

    // Handle rightmost bit as a half-adder (no carry input)
    // sum = a ^ b
    // c_out = a & b
    sum_bits |= ( a & mask) ^ ( b & mask);

    // The carry _out_ from this stage sets the carry in for the next,
    // that is, the next higher bit in the carry_bits value

    carry_bits |= ((a & mask) & (b & mask)) << 1u;

    // The remaining bits must be handled with the full adder logic. The last
    // adder in the chain's carry out becomes the carry output return
    // value of this function.
            mask = 1u << 1;

            sum_bits |= ((a & mask) ^ (b & mask) ^ carry_bits);
            carry_bits |= ((a & mask) & (b & mask)) << 1u; 

            mask = 1u << 2;
            sum_bits |= ((a & mask) ^ (b & mask) ^ carry_bits);
            carry_bits |= ((a & mask) & (b & mask)) << 1u;

            mask = 1u << 3;
            sum_bits |= ((a & mask) ^ (b & mask) ^ carry_bits);
            carry_bits |= ((a & mask) & (b & mask)) << 1u;

            mask = 1u << 4;
            sum_bits |= ((a & mask) ^ (b & mask) ^ carry_bits);
            carry_bits |= ((a & mask) & (b & mask)) << 1u;          

            mask = 1u << 5;
            sum_bits |= ((a & mask) ^ (b & mask) ^ carry_bits);
            carry_bits |= ((a & mask) & (b & mask)) << 1u;  
    // Handle bit 6 separately.
    mask = 1u << 6;
    sum_bits = ((a ^b) ^ carry_bits);
    carry_bits |= ((a & mask) & (b & mask)) << 1u;


// Determine the overflow by checking if a and b are both 1.
    bool overflow = false;
    if ((a & mask) & (b & mask))
        overflow = true;
    // ...
    //
 *sum_out = sum_bits;
 *carry_out = carry_bits;
 *overflow_out = overflow;
 cout << a << " + " << b << " = " << *sum_out << endl;;
 cout << "Carry: " << *carry_out << endl;
 cout << "Overflow: " << *overflow_out << endl;
    return true;
}
}

Dani AI

Generated

Short answer: is right about why you see a value of 2 — << 1 moves bit‑0 into bit‑1, so the integer 2 simply means “there is a carry into the next bit position.” The real problem in the code is mixing a multi‑bit carry field with single‑bit full‑adder logic and then treating the whole integer as “the carry bit.”

Two practical fixes

  • Keep a single 0/1 carry_in and update it each stage (simplest and least error‑prone).
  • Or keep a bitfield of carries but always extract the single bit for the position you are computing (e.g. carry_in = (carry_bits >> i) & 1u;) and, when returning a single final carry-out, extract the top bit: *carry_out = (carry_bits >> NUM_BITS) & 1u;.

A compact, robust approach (recommended)

unsigned carry_in = 0;
unsigned sum_bits = 0;
unsigned carry_into_msb = 0;

for (unsigned i = 0; i < NUM_BITS; ++i) {
    unsigned ai = (a >> i) & 1u;
    unsigned bi = (b >> i) & 1u;
    if (i == NUM_BITS - 1) carry_into_msb = carry_in;

    unsigned s = ai ^ bi ^ carry_in;
    sum_bits |= (s << i);

    unsigned carry_out = (ai & bi) | (carry_in & (ai ^ bi)); // full-adder carry
    carry_in = carry_out;
}

*sum_out = sum_bits;
*carry_out = carry_in;                 // single-bit final carry
*overflow_out = carry_into_msb ^ carry_in; // two's-complement overflow

Other quick notes

  • In your original code you sometimes use sum_bits = ... instead of |= and that can overwrite earlier bits.
  • If you prefer the bitfield pattern, always mask the carry to the same bit position when XOR/ORing, or you’ll get multi-bit values (what you saw as 2).
  • Add small unit tests (e.g. all pairs 0..127) and compare to a + b to validate sum, carry and overflow.

carry_bits |= ((a & mask) & (b & mask)) << 1u;

When a is 1, a & mask is 1, or in binary 00000001.
When b is 1, b & mask is 1, or in binary 00000001.

So ((a & mask) & (b & mask)) is00000001 & 00000001, which gives 00000001.

You then apply this:<< 1u which is left shifting 00000001, so you get 00000010, which is binary for 2.

That's why you get 2.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.