Препълването на цяло число със знак е като деление на нула - води до недефинирано поведение, така че трябва да проверите дали ще се случи преди да изпълните операцията с потенциално препълване. След като препълните, всички залози са изключени - вашият код може да направи всичко.
Макросите *_MAX
и _MIN
, дефинирани в <limits.h>
, са полезни за това, но трябва да внимавате да не извиквате недефинирано поведение в самите тестове. Например, за да проверите дали a * b
ще препълни дадено int a, b;
, можете да използвате:
if ((b > 0 && a <= INT_MAX / b && a >= INT_MIN / b) ||
(b == 0) ||
(b == -1 && a >= -INT_MAX) ||
(b < -1 && a >= INT_MAX / b && a <= INT_MIN / b))
{
result = a * b;
}
else
{
/* calculation would overflow */
}
(Имайте предвид, че един тънък капан, който това избягва, е, че не можете да изчислите INT_MIN / -1
- такова число не е гарантирано, че е представимо и наистина причинява фатален капан на общи платформи).
person
caf
schedule
07.10.2011