3 ms·
""" uint32_t a = ..., b = ...; uint32_t res = a + b; uint32_t carry = res < a; """ But note well: this trick doesn't work when there is also a
by less_less 2y ago
"""
uint32_t a = ..., b = ...;
uint32_t res = a + b;
uint32_t carry = res < a;
"""
But note well: this trick doesn't work when there is also a carry-in. That is,
uint32_t res = a + b + carry;
carry = res < a;
won't work when b = 0xFFFFFFFF and carry = 1, so you have to check for carries twice, or set `carry = res < a || (res == a && carry);` or similar. So if you are implementing bignums on an architecture that doesn't have ADC (such as RISC-V), or on a vector architecture where the performance would be bad, then you often need an alternative strategy such as using less than 32/64 bits per limb (whether that's half-size, or 30 bits or 51 bits or whatever).
- deleted 2y ago[deleted]
- worstspotgain 2y agoYep. Those are two additions, and naturally every full-word addition needs a separate overflow check. You can avoid the short-circuiting branches by just adding the carries: uint32_t res1 = a + carry; carry = res1 < a; uint32_t res2 = b + res1; carry += res2 < b;