# c++ 如何檢測整數溢出？

#include <limits.h>
int a = <something>;
int x = <something>;
a += x;              /* UB */
if (a < 0) {         /* unreliable test */
/* ... */
}

#include <limits.h>
int a = <something>;
int x = <something>;
if ((x > 0) && (a > INT_MAX - x)) /* `a + x` would overflow */;
if ((x < 0) && (a < INT_MIN - x)) /* `a + x` would underflow */;
// for subtraction
#include <limits.h>
int a = <something>;
int x = <something>;
if ((x < 0) && (a > INT_MAX + x)) /* `a - x` would overflow */;
if ((x > 0) && (a < INT_MIN + x)) /* `a - x` would underflow */;
// for multiplication
#include <limits.h>
int a = <something>;
int x = <something>;
if (a > INT_MAX / x) /* `a * x` would overflow */;
if ((a < INT_MIN / x)) /* `a * x` would underflow */;
// there may be need to check for -1 for two's complement machines
if ((a == -1) && (x == INT_MIN)) /* `a * x` can overflow */
if ((x == -1) && (a == INT_MIN)) /* `a * x` (or `a / x`) can overflow */

c++ c integer-overflow

unsigned long b, c, c_test;
...
c_test=c*b;         // Possible overflow
if (c_test/b != c) {/* There has been an overflow*/}
else c=c_test;      // No overflow

if ( b > ULONG_MAX / a ) // a * b would overflow

clang現在支持對有符號和無符號整數進行動態溢出檢查。 請參閱-fsanitize=integer切換。 目前，只有一個C ++編譯器支持完全支持動態溢出檢查以進行調試。

• x 0 == 1（9，8，7，6，5，4，3，2的所有置換都是解）
• x 1 == x（沒有可能的解決方案）
• 0 b == 0（無法解決）
• 1 b == 1（無法解決）
• a b ，a> 1，b> 1（非平凡）

9938.08^2 == 98765432
462.241^3 == 98765432
99.6899^4 == 98765432
39.7119^5 == 98765432
21.4998^6 == 98765432
13.8703^7 == 98765432
9.98448^8 == 98765432
7.73196^9 == 98765432
6.30174^10 == 98765432
5.33068^11 == 98765432
4.63679^12 == 98765432
4.12069^13 == 98765432
3.72429^14 == 98765432
3.41172^15 == 98765432
3.15982^16 == 98765432
2.95305^17 == 98765432
2.78064^18 == 98765432
2.63493^19 == 98765432
2.51033^20 == 98765432
2.40268^21 == 98765432
2.30883^22 == 98765432
2.22634^23 == 98765432
2.15332^24 == 98765432
2.08826^25 == 98765432
2.02995^26 == 98765432
1.97741^27 == 98765432

['0', '2', '4', '5', '6', '7', '8'] 2^84 = 7056
['1', '2', '3', '4', '5', '8', '9'] 2^59 = 3481
['0', '1', '2', '3', '4', '5', '8', '9'] 2^59 = 3481 (+leading zero)
['1', '2', '3', '5', '8'] 3^8 = 512
['0', '1', '2', '3', '5', '8'] 3^8 = 512 (+leading zero)
['1', '2', '4', '6'] 2^4 = 16
['0', '1', '2', '4', '6'] 2^4 = 16 (+leading zero)
['1', '2', '4', '6'] 4^2 = 16
['0', '1', '2', '4', '6'] 4^2 = 16 (+leading zero)
['1', '2', '8', '9'] 2^9 = 81
['0', '1', '2', '8', '9'] 2^9 = 81 (+leading zero)
['1', '3', '4', '8'] 4^3 = 81
['0', '1', '3', '4', '8'] 4^3 = 81 (+leading zero)
['2', '3', '6', '7', '9'] 6^3 = 729
['0', '2', '3', '6', '7', '9'] 6^3 = 729 (+leading zero)
['2', '3', '8'] 3^2 = 8
['0', '2', '3', '8'] 3^2 = 8 (+leading zero)
['2', '3', '9'] 2^3 = 9
['0', '2', '3', '9'] 2^3 = 9 (+leading zero)
['2', '4', '6', '8'] 2^8 = 64
['0', '2', '4', '6', '8'] 2^8 = 64 (+leading zero)
['2', '4', '7', '9'] 2^7 = 49
['0', '2', '4', '7', '9'] 2^7 = 49 (+leading zero)

import math

m = 98765432
l = []
for i in xrange(2, 98765432):
inv = 1.0/i
r = m**inv
if (r < 2.0): break
top = int(math.floor(r))
assert(top <= m)

for j in xrange(2, top+1):
s = str(i) + str(j) + str(j**i)
l.append((sorted(s), i, j, j**i))
assert(j**i <= m)

l.sort()
for s, i, j, ji in l:
assert(ji <= m)
ss = sorted(set(s))
if s == ss:
print '%s %d^%d = %d' % (s, i, j, ji)

# Try with non significant zero somewhere
s = ['0'] + s
ss = sorted(set(s))
if s == ss:
print '%s %d^%d = %d (+leading zero)' % (s, i, j, ji)

FPE_INTOVF_TRAP整數溢出（除非您以硬件特定的方式啟用溢出陷阱，否則在C程序中不可能）。

uint32_t x, y;
uint32_t value = x + y;
bool overflow = value < (x | y);

uint32_t x, y;
uint32_t value = x + y;
bool overflow = value < x; // Alternatively "value < y" should also work

1. 獲取表示類型MAXVALUE和MINVALUE的最大和最小可能值的常量。

2. 計算和比較操作數的符號。

一個。 如果任一值為零，則加法和減法都不會溢出。 跳過剩餘的測試。

灣 如果符號相反，則添加不能溢出。 跳過剩餘的測試。

C。 如果符號相同，則減法不能溢出。 跳過剩餘的測試。

3. 測試MAXVALUE的正溢出。

一個。 如果兩個符號均為正數，且MAXVALUE - A <B，則加法將溢出。

灣 如果B的符號是負數且MAXVALUE - A <-B，則減法將溢出。

4. 測試MINVALUE的負溢出。

一個。 如果兩個符號均為負值且MINVALUE - A> B，則加法將溢出。

灣 如果A的符號是負數並且MINVALUE - A> B，則減法將溢出。

5. 否則，不會溢出。

1. 獲取表示類型MAXVALUE和MINVALUE的最大和最小可能值的常量。

2. 計算並比較操作數的大小（絕對值）。 （下面，假設A和B是這些大小，而不是簽名的原稿。）

一個。 如果任一值為零，則乘法不能溢出，並且除法將產生零或無窮大。

灣 如果任一值為1，則乘法和除法不能溢出。

C。 如果一個操作數的大小低於1，另一個大於1，則乘法不能溢出。

d。 如果幅度都小於1，則劃分不能溢出。

3. 測試MAXVALUE的正溢出。

一個。 如果兩個操作數都大於1且MAXVALUE / A <B，則乘法將溢出。

灣 如果B小於1並且MAXVALUE * B <A，那麼除法將溢出。

4. 否則，不會溢出。

CERT has developed a new approach to detecting and reporting signed integer overflow, unsigned integer wrapping, and integer truncation using the "as-if" infinitely ranged (AIR) integer model. CERT has published a technical report describing the model and produced a working prototype based on GCC 4.4.0 and GCC 4.5.0.

The AIR integer model either produces a value equivalent to one that would have been obtained using infinitely ranged integers or results in a runtime constraint violation. Unlike previous integer models, AIR integers do not require precise traps, and consequently do not break or inhibit most existing optimizations.

Calculate the results with doubles. They have 15 significant digits. Your requirement has a hard upper bound on c of 10 8 — it can have at most 8 digits. Hence, the result will be precise if it's in range, and it will not overflow otherwise.

You can't access the overflow flag from C/C++.

I don't agree with this. You could write some inline asm and use a jo (jump overflow) instruction assuming you are on x86 to trap the overflow. Of course you code would no longer be portable to other architectures.

look at info as and info gcc .

Inline assembly lets you check the overflow bit directly. If you are going to be using C++, you really should learn assembly.

bool addition_is_safe(unsigned int a, unsigned int b)
{
unsigned int L_Mask = std::numeric_limits<unsigned int>::max();

return ( a == 0 || b == 0 );
}

This uses machine-architecture safe, in that 64-bit and 32-bit unsigned integers will still work fine. Basically, I create a mask that will mask out all but the most significant bit. Then, I mask both integers, and if either of them do not have that bit set, then addition is safe.

This would be even faster if you pre-initialize the mask in some constructor, since it never changes.

mozilla::CheckedInt<T> provides overflow-checked integer math for integer type T (using compiler intrinsics on clang and gcc as available). The code is under MPL 2.0 and depends on three ( IntegerTypeTraits.h , Attributes.h and Compiler.h ) other header-only non-standard library headers plus Mozilla-specific assertion machinery . You probably want to replace the assertion machinery if you import the code.

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

int mltovf(int a, int b)
{
if (a && b) return abs(a) > MAX/abs(b);
else return 0;
}

main()
{
int a, b;

for (a = 0; a <= MAX; a++)
for (b = 0; b < MAX; b++) {

if (mltovf(a, b) != (a*b > MAX))
printf("Bad calculation: a: %d b: %d\n", a, b);

}
}

It depends what you use it for. Performing unsigned long(DWORD) addition or Multiplication the best solution is to use ULARGE_INTEGER.

ULARGE_INTEGER is a structure of two DWORDs. The full value can be accessed as "QuadPart" while the hi DWORD is accessed as "HighPart" and the low DWORD is accessed as "LowPart"

DWORD My Addition(DWORD Value_A,DWORD Value_B) { ULARGE_INTEGER a,b;

b.LowPart = Value_A;  // a 32 bit value(up to 32 bit)
b.HighPart = 0;
a.LowPart = Value_B;  // a 32 bit value(up to 32 bit)
a.HighPart = 0;

// if  a.HighPart
// Then a.HighPart contains the overflow(carry)

return (a.LowPart + a.HighPart)

// any overflow is stored in a.HighPart(up to 32 bits)

### Tags

c++   c   integer-overflow