ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
There is no overflow in unsigned arithmetic. If one operand is unsigned and the other is signed, than the signed is converted into unsigned. Overflow can occur if both operands are signed.
Code:
if ( (unsigned) a + (unsigned) b > INT_MAX )
complain();
Originally posted by GtkUser
[B]There is no overflow in unsigned arithmetic.[B]
Hmmm...
Suppose type int has 16 bit capacity. Therefore maximal unsigned int is 2^16 - 1 = 65535. Suppose have two vars:
unsigned int a = 60000;
unsigned int b = 40000;
and want to add a to b:
unsigned int c = a + b;
Correct result in this case is 100000 but var c due to 16 bit capacity will contain incorrect val 44465.
How to detect this situation???
In simplest cases when used only '+' and '-' operations I can try detect overflow with help of INT_MIN/MAX. But what about other mathematical operations '/', '*', '%' etc?
P.S. Thenks for reference to book. I try to find it.
My computer gives me: 2147483647
So that is the max.
Now I run this program:
Code:
#include<stdio.h>
#include<limits.h>
int main() {
int i;
int x = 2;
int sum = 1;
for ( i = 0; i < 32; ++i )
{
sum *= x;
printf("%d\n", sum);
}
return 0;
}
So there is some overflow! The last couple of multiples of 2.
Now I revise the program by adding the overflow check:
Code:
#include<stdio.h>
#include<limits.h>
int main() {
int i;
int x = 2;
int sum = 1;
for ( i = 0; i < 32; ++i )
{
if (! ( (unsigned) sum * (unsigned) x > INT_MAX) )
sum *= x;
printf("%d\n", sum);
}
return 0;
}
Originally posted by GtkUser My computer gives me: 2147483647
So that is the max.
Now I run this program:
Code:
#include<stdio.h>
#include<limits.h>
int main() {
int i;
int x = 2;
int sum = 1;
for ( i = 0; i < 32; ++i )
{
sum *= x;
printf("%d\n", sum);
}
return 0;
}
So there is some overflow! The last couple of multiples of 2.
Now I revise the program by adding the overflow check:
Code:
#include<stdio.h>
#include<limits.h>
int main() {
int i;
int x = 2;
int sum = 1;
for ( i = 0; i < 32; ++i )
{
if (! ( (unsigned) sum * (unsigned) x > INT_MAX) )
sum *= x;
printf("%d\n", sum);
}
return 0;
}
This is work Many thanks. But is this approach correct???
I can guess that expression (unsigned) sum * (unsigned) x is calculated in FPU with 64/80 bit precise. But I think that on more weak hard (suppose 8088) this code will return incorrect result.
Moreover on your PC it can produce error result if result of expression will be more than 2^80.
It is supposed to be correct, for all implementations that define an INT_MAX in <limits.h>
The book says that all unsigned operations are done modulo 2^n, where n is the number of bits in the result. It says that there is no such thing as overflow in unsigned arithmetic.
If you can, test is out on other architectures before deploying. I don't know the mathematical details. I am just going by the book, and I only figured out this example to demonstrate it.
One method I've used to check in advance whether overflow will occur is:
Code:
int x;
int y;
// other stuff, assigns some values to x and y
if ( x < INT_MAX - y )
z = x + y;
else
complain();
or:
Code:
// ...
if ( x < INT_MAX / y )
z = x * y;
else
complain();
Granted, in a way this involves doing the computation twice, but this will at least make sure x+y (or x*y in the second example) is less than INT_MAX before doing the calculation. (Hope this makes sense... if you know your algebra, it will )
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.