For a fixed length integer, you can just unroll a ripple carry adder. In the worst case, a carry signal has to propagate all the way from the least significant bit to the most significant bit.
Like this (only slightly tested) (to avoid the C-purists' wrath, I will call this C# code)
int add_3bits(int x, int y)
{
int c = x & y;
x = x ^ y;
y = c << 1;
//
c = x & y; //
x = x ^ y; // | for more bits, insert more of these blocks
y = c << 1; // /
//
// optimized last iteration
return (x ^ y) & 7; // for more bits, change that mask
}
If you do it for as many bits as your integer will hold, you won't need the mask in the end.
That's not very efficient, clearly. For 3 bits it's fine, but for 32 bits it becomes quite long. A Kogge-Stone adder (one of the O(log n) delay adder circuits) is also surprisingly easy to implement in software (in hardware you have to deal with a lot of wires, software doesn't have that problem).
For example: (verified using my website)
static uint add_32bits(uint x, uint y)
{
uint p = x ^ y;
uint g = x & y;
g |= p & (g << 1);
p &= p << 1;
g |= p & (g << 2);
p &= p << 2;
g |= p & (g << 4);
p &= p << 4;
g |= p & (g << 8);
p &= p << 8;
g |= p & (g << 16);
return x ^ y ^ (g << 1);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…