I'm trying to detect the overflow when adding a signed offset to an unsigned position
uint32 position;
int32 offset; // it could be negative
uint32 position = position+offset;
How can I check whether the result is overflow or underflow?
I have thought of an ugly way but not sure of its correctness.
- underflow:
offset < 0 && position + offset >= position
- overflow:
offset > 0 && position + offset <= position
And I'm also wondering if there's a more elegant way to do it.
Update:
What's the best solution if offset is long?
uint32 position;
long offset; // it could be negative
uint32 position = position+offset;
Your test(s) is (are) correct. I don't see a more elegant way right now, perhaps there isn't.
Why the conditions are correct: arithmetic on
uint32_t
is arithmetic modulo 2^32. Conversion fromint32_t
touint32_t
is normally the reinterpretation of the bit-pattern (in any case, as @caf pointed out, it's reduction modulo 2^32 here, so it definitely works). Regardposition
andoffset
as arbitrary precision integers. Overflow happens if and only ifposition + offset >= 2^32
. Butoffset < 2^31
, soposition + offset < position + 2^31
, which is less thanposition + 2^32
, the next value that reduces toposition
modulo 2^32, so asuint32_t
, thenposition + offset < position
. On the other hand, ifoffset > 0
andposition + offset < position
, evidently overflow has occurred. Underflow happens if and only ifposition + offset < 0
as mathematical integers. Sinceoffset >= -2^31
, similar reasoning shows that underflow has occurred if and only ifoffset < 0 && position + offset > position
.