I am experimenting with c++. I wrote a simple function that finds the area of a triangle using very large numbers.
I pass two large numbers into the function, and from a separate function, getValue() I return a separate value from a different equation. I'm curious why when I place the 1 on the line outside the parenthesis, like so:
return (long long)(a - b / 2.0) + b + 1;
I get the value 9007200509008001
And when I keep the 1 inside the parenthesis, like so:
return (long long)(a - b / 2.0 + 1) + b;
I get 9007200509008000
The second value is one less than the first, even though the computation should result in equal answers.
#include <iostream>
double triangleArea(int b, int h)
{
long long bh = (long long)b * h;
return 0.5 * bh;
}
long long getValue()
{
int deltaY = 18014400;
int deltaX = 1000000000;
long b = deltaY + deltaX + 1600;
double a = triangleArea(deltaX, deltaY);
return (long long)(a - b / 2.0) + b + 1;
}
int main(int argc, char **argv)
{
std::cout << getValue() << std::endl;
}
I'm sure the answer is probably obvious to some people, but I can't wrap my head around it. Can someone explain?
When you divide by 2.0 you have an implicit conversion to double. Double accuracy is limited to about 15 decimal digits. So what happens to the 16th digit is perfectly defined, but may not be what you expect.
If you need accuracy, try to use long long or unsigned long long and carefully control that you have no overflow. If it is not enough, you will have to use multi-precision arithmetic (for example GMP). Because as soon as you use double floating points, you are limited to 53 binary digits of accuracy, or about 15-16 decimal digits.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With