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.
.03 cannot be represented correctly and precisely in Floating Point. Period. If you actually dump the contents of the variable and examine it you will see. Try gdb to examine your FP variables. But read about IEEE 754 someplace before you start or it won't make sense.
Yes I know about the failure of floating point numbers - that's way I need to convert them.
But this is a failure not in some last positions this is a failure at the first position.
You know that that is not an error of floating point numbers. They are precise in a range of many digits and value and that's were my error occurs. To convert 6.0000 to 6 (int) is no problem but to round 6.4995 to 6 can be one. With floating point numbers you have a deviation maybe of 1/10exp9 but not as big as 20% of your number.
Okay let us assume that .03 is held as .0299999, when this number is multiplied by 2 the sum will be .0599998, which may actually be held as .0599999 but when this is multiplied by 100 it will give 5.99999. Converting this to an integer through straight type casting will give 5. In all this calculation the error is negligible.
void test( double d )
{
long int x;
unsigned int ui=2;
x = long( d * (ui * 100) );
std::cout << x << std::endl;
x = long( d * (ui * 10000000) );
std::cout << x << std::endl;
double dd = d * ui * 100;
x = int(dd);
std::cout << dd << std::endl;
std::cout << x << std::endl;
}
int main()
{
test(.03);
return 0;
}
and you guess that the result is 6, but not in my case - it's 5 !!
You can use ceil too, the result is 5 in my case.
Or something like this:
Code:
double dd = d * ui * 10000;
x = int(dd)/100;
The result is 5 !!
And my FPU is set to round nearest,
so in every case it should be rounded to 6.
Now I want to know if this error is an error of my CPU/FPU type or if others have
this problem too. Then it can be an error of gcc and glibc.
The joke is that QT/KDE prints dd correctly (6.00), but if I convert this value to
integer ( int(dd) ) it is 5 !!!
GCC uses the FPU command FRNDINT (round to integer) for "int(dd)" by default, and now I guess that my
FPU does this work wrong on every third floating point number (0.03, 0,06, 0,09, 0,12...).
At the moment I do the conversion like this:
write the floating point number to a string and read it back as integer is as fast as the FPU command FRNDINT.
To make it clear, FRNDINT is not something off c++ or a function, it's a FPU command and has the machine code D9 FC, c++ only presents it to you as int() or long().
Instead of FRNDINT you can use any rounding function written in your favorite language and the result will be exactly what you wanted to get - 6 .
But it's a very doubtful situation if int() or long() don't convert right to integers.
To make it clear, FRNDINT is not something off c++ or a function, it's a FPU command and has the machine code D9 FC, c++ only presents it to you as int() or long().
I am aware that FRNDINT is an FPU instruction. So why don't you tell us exactly how you are using it. If you are assuming that the typecasting int() is using it then yes you are correct and it is using it with the rounding flag set to towards zero, hence giving the results in a consistent manner.
If you are using it in a different way then tell us, how else can we assist?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.