424,987 Members | 1,607 Online
Need help? Post your question and get tips & solutions from a community of 424,987 IT Pros & Developers. It's quick & easy.

# Detecting integer overflow

 P: n/a Given two longs: long a = ...; long b = ...; What's the simplest/fastest way of performing a simple operation on longs and detecting overflow? long c = a + b; // but branch on overflow One way is to perform the operation with long long: long long temp = (long long)a + b; c = (long)temp; if ((long long)c != temp) goto blast; but it seems a bit strange that I'd have to use long long for all computations, to deal with the relatively rare case of overflow. Sep 21 '06 #1
8 Replies

 P: n/a Ole Nielsby wrote: Given two longs: long a = ...; long b = ...; What's the simplest/fastest way of performing a simple operation on longs and detecting overflow? long c = a + b; // but branch on overflow if (b <= LONG_MAX - a) { c = a + b; } else { // Overflow } TODO: a and b are both negative. > One way is to perform the operation with long long: long long temp = (long long)a + b; c = (long)temp; Remember : If temp cannot be represented in long you are invoking implementation defined behavior. Just check if temp belongs to [LONG_MIN, LONG_MAX] Krishanu Sep 21 '06 #2

 P: n/a Ole Nielsby wrote: Given two longs: long a = ...; long b = ...; What's the simplest/fastest way of performing a simple operation on longs and detecting overflow? long c = a + b; // but branch on overflow One way is to perform the operation with long long: long long temp = (long long)a + b; c = (long)temp; if ((long long)c != temp) goto blast; but it seems a bit strange that I'd have to use long long for all computations, to deal with the relatively rare case of overflow. Would the following work? long c = a + b; if (a 0 && b 0 && c < 0) Overflow(); Sep 21 '06 #3

 P: n/a Ole Nielsby posted: What's the simplest/fastest way of performing a simple operation on longs and detecting overflow? Off the top of my head, you could test for a negative answer where a positive answer was expected, and vice versa -- but that's only after the overflow has taken place. E.g.: long a=3000000000,b=4000000000; long c = a*b; if(c < 0) throw Overflow(); Ofcourse, you want to make sure beforehand that overflow doesn't invoke undefined behaviour: COMPILE_TIME_ASSERT( std::numeric_limits::modulo ); -- Frederick Gotham Sep 21 '06 #4

 P: n/a Krishanu Debnath [...]What's the simplest/fastest way of performing a simpleoperation on longs and detecting overflow? long c = a + b; // but branch on overflow if (b <= LONG_MAX - a) {c = a + b;} else {/*Overflow*/} TODO: a and b are both negative. That's the problem. It would take several conditional jumps to test using nothing but longs, and conditional jumps are bad for performance. >One way is to perform the operation with long long: long long temp = (long long)a + b; c = (long)temp; Remember : If temp cannot be represented in long you are invoking implementation defined behavior. I think this doesn't matter, as long as a long is returned. If c doesn't represent temp, the next comparison will detect it: > if ((long long)c != temp) goto blast; Thanks to those who suggested other solutions - but I'll stick with the long long way for now unless something more elegant comes up - as far as I can see, the other suggestions involve multiple conditional jumps. I just hoped there would be an intrinsic function or some language feature I had overlooked (like the checked/unchecked keywords of C#) that allowed me to get code like: add eax, ebx jo overflow from the C++ compilers (assuming register variables). It puzzles me that this trivial asm is so complicated in C++. Regards/Ole Sep 21 '06 #5

 P: n/a Ole Nielsby wrote: >> long c = a + b; // but branch on overflow if (b <= LONG_MAX - a) {c = a + b;} else {/*Overflow*/}TODO: a and b are both negative. That's the problem. It would take several conditional jumps to test using nothing but longs, and conditional jumps are bad for performance. So you want to branch without jumping? I think this doesn't matter, as long as a long is returned. If c doesn't represent temp, the next comparison will detect it: >> if ((long long)c != temp) goto blast; And this is not a conditional jump? And the extension to long long and the comparison takes no time? Maybe your way is faster than the others suggested, but you can't know for sure. -- Salu2 Sep 21 '06 #6

 P: n/a Julián Albo

 P: n/a Ole Nielsby wrote: >And this is not a conditional jump? I was just pointing out that my solution has fewer conditional jumps than the others. >And the extension to long long and the comparison takes notime? Generally, such operations are a lot faster than conditional jumps because they are predictable and don't mess up the instruction pipelines the way conditional jumps do. But you are no choosing between a way without jumps and one with jumps, just between more or less jumps. It's no so easy to predict the predictability ;) -- Salu2 Sep 22 '06 #8

 P: n/a An easier test than true overflow is whether your int (let's say it's 32 bits) has exceeded half its range, either in the positive or negative direction: int overflow = 1 & ((x>>30) ^ (x>>31)); Think of it as an overflow of a 31 bit integer. In many algorithms if the magnitude of the value has become this large, it will truly overflow soon. Steve Sep 22 '06 #9

### This discussion thread is closed

Replies have been disabled for this discussion.