Page 1 of 1
overflow (C++)
Posted: Sun Feb 03, 2008 6:37 pm
by Zacariaz
A simple question, which i should allready know the answer too (well i don't)
How do i check for overflow?
fx.
unsigned char var = 6*64;
Obiously this will result in overflow and wrap around resulting in an incorrect result. 128 i should think.
If this should happen, i don't need to know the result, just that the result is to large to fit into the datatype used.
In my scenario, where im going to multiply alot of rather large numbers, i know that this, sooner or later, will be a problem and therefore i am in desperate need of a solution.
Thanks.
Posted: Sun Feb 03, 2008 7:05 pm
by Brynet-Inc
I assume C++ still has the limits.h header.. or something of equivalent relevance.
I suppose you could...
Code: Select all
if((val1 * val2) > UCHAR_MAX)
return -1;
unsigned char var = (unsigned char)(val * val2);
But really, I think this is a bit over the top...
Posted: Sun Feb 03, 2008 9:47 pm
by Zacariaz
I could use that methode for some situation, but using your example consider this:
Code: Select all
unsigned long long var1, var2;
var1 = 0xffffffffffffffffull;
var2 = 1ull;
if((var1 + var2) > UINT64_MAX)...
I may be mistaken, but i don't think this is going to work, the cpu register only go so high.
As i see it i need to check the overflow flag, but i have know idea howto in C++.
Posted: Sun Feb 03, 2008 10:12 pm
by Brynet-Inc
You didn't say anything about > 64bit integers in your initial post..
Obviously that would be something different...
It has already been pointed out in the past that you should be using 3rd party libraries for very long numbers.. what is your obsession with them?
Posted: Mon Feb 04, 2008 12:48 am
by B.E
you could do this:
tempx = x
x = x+y
if (x > tempx)
// overflow didn't occur
else
// overflow did occur
Posted: Mon Feb 04, 2008 5:24 am
by Zacariaz
Yes, but as i demonstrated, that doesnt allways work.
True, you can often the bigger of the two numbers and then if the result is smaller, we have overflow, however this is only guarantied to work if we add or subtract (of course doing everything in reverse), not if we multiply or divide (acutally im not quite sure about anything when it comes to division) and multiplying alot of number is exactly what i need to do.
Should it be of any interest the math looks like this:
A little big i know, but thats what happens when you do thing in a hurry.
Anyway, it is obious that you can't just do the math like: (1/2)(2/3)(4/5)(6/7)(10/11)... you'll find that precision be a problem before long, fortunantly it is easy to rewrite it:
(1*2*4*6*10)/(2*3*5*7*11) this enables us to wait with the division, bus as we all know, when multiplying alot of large numbers you'll quicklyget a rather large result. That we allso have a solution for:(1*2*4*6*10)/(2*3*5*7*11)=(4*2*2)/(7*11).
So basicly i have my methodes in order. this way i can do the math in stages and avoid any significant precision problems, but i do need to be sure that no limits are exceeded.
Posted: Mon Feb 04, 2008 8:05 am
by Solar
Zacariaz wrote:As i see it i need to check the overflow flag, but i have now idea howto in C++.
You can't.
But perhaps doing the calculation / overflow check in inline assembler helps things? Faster than the C++ workarounds for sure...
Posted: Mon Feb 04, 2008 10:45 am
by Zacariaz
i considered this, but i never learned inline assembly. It shouldn't be hard, but every tutorial or documentation i find seems to have no working examples, it refuses to compile, and that goes for anything i do myself allso. Maybe you could point me in the right direction? obiously im doing something wrong.
Posted: Mon Feb 04, 2008 11:03 am
by cyr1x
Try this:
Code: Select all
bool checkOverflowFlag() { int eflags; asm volatile("pushf; popl %0" : "=g"(eflags)); return (eflags >> 11) & 1; }
I'm not 100% sure if the OverflowFlag is bit 11 in the EFLAGS-register.