Assuming you have two 32-bit DWORD x and y, how can you detect if their sum would result in an overflow, but without resorting to native assembly to examine the carry flag. I'd like something with arithmetic or binary operators. I figured there might be some bit testing methods to figure it out. Thanks
Asked
Active
Viewed 1,407 times
2 Answers
5
Why not test the sum?
DWORD sum = x + y;
bool const overflow = (sum < x);

Cheers and hth. - Alf
- 142,714
- 15
- 209
- 331

Stephen Quan
- 21,481
- 4
- 88
- 75
-
1With x = 5 and y = -5 you'll get true despite it being no overflow, as the sum is less then x. – Mario Feb 05 '12 at 10:34
-
1
-
2@Mario: this is not really correct. `-5` is not a valid value for unsigned int, and becomes 0xFFFFFFFB when assigned to a DWORD. So x+y = 0xFFFFFFFB + 5 = 0x100000000, and the 32-bit result of 0 is really a consequence of overflow. – kkm inactive - support strike Feb 05 '12 at 10:39
-
1Needless extra checking, lack of `const` (i.e. not teaching good practice). However I think it would probably feel unfair if I downvoted. But please fix. ;-) Cheers, – Cheers and hth. - Alf Feb 05 '12 at 10:45
-
1@BicycleDude: OK I just fixed your code myself. But please do heed comments about things needing to be fixed. Don't take it for granted that others will step in and fix things for you. – Cheers and hth. - Alf Feb 05 '12 at 11:40
-
1+1 Thx Alf for removing the needless check. I was afk and just got back. – Stephen Quan Feb 05 '12 at 13:03
1
Should pretty much save to assume, tell me if I missed any case (this won't work in compilers adhering to C++98 or newer standards):
int overflowSum(DWORD a, DWORD b) {
return (b > 0) ? (a + b < a) : (a + b > a);
}
If you consider your DWORD to be unsigned, you can simplify it:
int overflowSum(DWORD a, DWROD b) {
return a + b < a;
}

Mario
- 35,726
- 5
- 62
- 78
-
3
-
Since the behaviour for signed integer overflow is undefined, compiler optimisers can ***and do*** make the assumption that your code does not cause signed integers to overflow. See [here](http://www.airs.com/blog/archives/120) for more information. – dreamlax Feb 05 '12 at 10:39
-
dreamlax is correct. signed overflow behavior is not specified in C++, and your approach may be dependent not only on a particular CPU architecture, but also on a mode it is currently in. Very unsafe and unportable. – kkm inactive - support strike Feb 05 '12 at 10:42
-
+1 for not adding needless checking. note to @dreamlax: the OP's terminology, using "DWORD", implies the Windows or at least PC platform. – Cheers and hth. - Alf Feb 05 '12 at 10:44
-
@AlfP.Steinbach: The operating system or architecture make no difference to the fact that some compilers make optimisations with the assumption that signed integer types won't overflow. – dreamlax Feb 05 '12 at 10:50
-
@AlfP.Steinbach: Even assuming DWORD to imply Windows, that does not define a CPU. Windows Phone would also using same definitions, and that runs on many CPUs. Or a different compiler whatsoever, as dreamlax already noted. – kkm inactive - support strike Feb 05 '12 at 10:56
-
@Mario: not `int`, only `unsigned int` (or `DWORD`) will do. With `int`s, the result might be incorrect! Use this: `DWORD overflowSum(DWORD a, DWORD b)` – kkm inactive - support strike Feb 05 '12 at 10:58
-
@AlfP.Steinbach: Please do not attempt to read my mind. I am answering here *just because*. As for the reference, you may want to read this: http://stackoverflow.com/questions/3679047/integer-overflow-in-c-standards-and-compilers – kkm inactive - support strike Feb 05 '12 at 11:35
-
@kkm: that's not a reference supporting your statements. please stop spouting disinformation on stack overflow. thanks. – Cheers and hth. - Alf Feb 05 '12 at 11:37
-
@AlfP.Steinbach: You stated that DWORD *implies [...] PC platform*. I only noted that this is not correct, as there are varieties of Windows not running on a PC platform, Windows Phone being one example. I do not see what is incorrect in my statement. If you have a reference indicating that Windows Phone does not run Windows, or that the type DWORD is defined only in Windows SDK for a PC platform, I would be most obliged if you posted it. Thanks. – kkm inactive - support strike Feb 05 '12 at 11:50
-
@kkm: quoting you: "signed overflow behavior is not specified in C++, and your approach may be dependent not only on a particular CPU architecture, but also on a mode it is currently in. Very unsafe and unportable." that's incorrect for the OP's question, which relies on platform guarantees. in addition you have now twice tried to mislead readers about my comments on that. please stop spouting disinformation on stack overflow. thanks. – Cheers and hth. - Alf Feb 06 '12 at 10:33
-
@AlfP.Steinbach: Exactly, that was my point. Previous version of Mario's code used ints, and that was both out of context of the question and undefined in the language. please stop spouting disinformation on stack overflow. thanks. – kkm inactive - support strike Feb 06 '12 at 11:00
-
@kkm: `int` in Windows (even 64-bit Windows) is 32-bit, two's complement with no trapping. DWORD in Windows is also 32-bit. The code relies on that, not on the language standard's cross platform guarantees. I.e., your comments are simply uninformed meaningless disinformation. Kindly stop posting such disinformation on stack overflow. – Cheers and hth. - Alf Feb 06 '12 at 11:31
-
1@AlfP.Steinbach: Can you please restate your point? Am I understanding correctly that you are saying that, despite the fact that C++ standard does not define the behavior of signed integer overflow, relying on a specific behavior of it is *correct* on all varieties of Windows with any compiler? – kkm inactive - support strike Feb 06 '12 at 12:21