Fedora Linux Support Community & Resources Center
  #1  
Old 24th August 2009, 07:15 PM
hurleyef Offline
Registered User
 
Join Date: Jul 2009
Posts: 19
windows_98_nt_2000safari
g++: trouble converting double to int

When casting a double into an int certain numbers will be decremented by one. I didn't see any pattern to the numbers that were properly converted and those that weren't.

for example:
Code:
#include iostream
using namespace std
void main()
{
     double n=574.05;
     n=n*100;
     cout<<n<<endl;
     int m=(int)n;
     cout<<m<<endl;
     cout<<n<<endl;
     return 0;
}
returns:
Code:
57405
57404
57405
This happens on both windows 7 rc1 (64bit) and fedora 11 (32bit). However, when I used visual studio.net 2003 at school to compile my code, I did not get this error. I just install gcc-c++ on fedora last night to test it, so I imagine I'm using the latest version.

This is driving me crazy. None of the visual-crap sweets work right in windows 7, so that's not an option at home. If anyone has a solution, please let me know.

Thanks.
Reply With Quote
  #2  
Old 24th August 2009, 07:53 PM
Gödel's Avatar
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,095
linuxfedorafirefox
Try the following in windows, does it produce the same output? This is on 32bit gcc, and as you can see the internal representation is 57404.999999..., windows compilere may be representing it internally as 57405.000000...

Code:
#include <iostream>
using namespace std;
int main()
{
     double n=574.05;
     n=n*100;
     cout.precision(18);
     cout<<n<<endl;
     int m=(int)n;
     cout<<m<<endl;
     cout<<n<<endl;
     return 0;
}
Code:
$ g++ -o gcctest gcctest.cpp 
$ ./gcctest 
57404.9999999999927
57404
57404.9999999999927
Reply With Quote
  #3  
Old 24th August 2009, 08:02 PM
hurleyef Offline
Registered User
 
Join Date: Jul 2009
Posts: 19
windows_98_nt_2000safari
yep, same output.

After posting this thread I finally got visual c++ working. Compiling it with that results in the same output.
Reply With Quote
  #4  
Old 24th August 2009, 08:04 PM
newiLuvatar's Avatar
newiLuvatar Offline
Registered User
 
Join Date: Aug 2007
Location: Switzerland
Posts: 479
linuxfedorafirefox
I guess it might be some rounding error, I have the same outputs as you...
however, the problem disappears if you set n to e.g. 574.10, or to 574.005, and multiply by 1000.
but this is not an satisfying answer (neither for you nor me). I'll keep looking into this.

EDIT: just saw the post by gödel. that would explain some things...

Last edited by newiLuvatar; 24th August 2009 at 08:07 PM.
Reply With Quote
  #5  
Old 24th August 2009, 08:52 PM
David Becker Offline
Registered User
 
Join Date: Feb 2006
Posts: 780
linuxfedorafirefox
It's more of representation failure.

You've hit a value that has trouble being represented in binary. The (implementor of the) binary representation may choose an adjacent representation that comes closer to the actual value.

The following notion provides some of the freedom:

0.9999999 (infinitely repeating 9's) = 1

'=' means exactly, not approximately.

David
Reply With Quote
  #6  
Old 25th August 2009, 04:27 AM
hurleyef Offline
Registered User
 
Join Date: Jul 2009
Posts: 19
windows_98_nt_2000safari
Thanks for the help.
That explains it.
Reply With Quote
  #7  
Old 25th August 2009, 07:39 AM
pete_1967 Offline
Clueless in a Cuckooland
 
Join Date: Mar 2006
Location: Here now, elsewhere tomorrow.
Posts: 3,929
linuxfedorafirefox
Here's something fun for you:
Code:
#include <stdio.h>
int main(void) {
double n = 574.05;
int m;
printf("%.10lf\n", n * 100);
n = n * 100;
printf("%.10lf\n", n);
m = (int) n;
printf("%d\n", m);

return 0;
}
Code:
gcc -o castint castint.c

 ./castint 
57405.0000000000
57405.0000000000
57404
__________________
A Drink is Not Just For Christmas - SaskyCom :thumb:


“Give a man a fish; you have fed him for today. Teach a man to fish; and you have fed him for a lifetime” so now go and...
RTFM FIRST: http://docs.fedoraproject.org/ & http://rute.2038bug.com/index.html.gz

Last edited by pete_1967; 25th August 2009 at 08:00 AM.
Reply With Quote
  #8  
Old 25th August 2009, 10:00 AM
Gödel's Avatar
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,095
linuxfedorafirefox
with full precision

Code:
$ cat castint.c 
#include <stdio.h>
int main(void) {
double n = 574.05;
int m;
printf("%.14lf\n", n * 100);
n = n * 100;
printf("%.14lf\n", n);
m = (int) n;
printf("%d\n", m);

return 0;
}

$ gcc -o castint castint.c 
$ ./castint 
57404.99999999999272
57404.99999999999272
57404
Reply With Quote
  #9  
Old 25th August 2009, 11:07 AM
pete_1967 Offline
Clueless in a Cuckooland
 
Join Date: Mar 2006
Location: Here now, elsewhere tomorrow.
Posts: 3,929
windows_xp_2003ie
Quote:
Originally Posted by Gödel View Post
with full precision

Code:
$ cat castint.c 
#include <stdio.h>
int main(void) {
double n = 574.05;
int m;
printf("%.14lf\n", n * 100);
n = n * 100;
printf("%.14lf\n", n);
m = (int) n;
printf("%d\n", m);

return 0;
}

$ gcc -o castint castint.c 
$ ./castint 
57404.99999999999272
57404.99999999999272
57404
Spoilsport.
__________________
A Drink is Not Just For Christmas - SaskyCom :thumb:


“Give a man a fish; you have fed him for today. Teach a man to fish; and you have fed him for a lifetime” so now go and...
RTFM FIRST: http://docs.fedoraproject.org/ & http://rute.2038bug.com/index.html.gz
Reply With Quote
  #10  
Old 25th August 2009, 12:02 PM
Gödel's Avatar
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,095
linuxfedorafirefox
sorry

The thing that has not been resolved is why Visual Studio .NET 2003 "at school" rounded to 57405, which may be due to the compiler representing the double differently to the other compilers, but that sounds unlikely.
Reply With Quote
  #11  
Old 25th August 2009, 03:47 PM
hurleyef Offline
Registered User
 
Join Date: Jul 2009
Posts: 19
linuxfedorafirefox
Quote:
Originally Posted by Gödel View Post
sorry

The thing that has not been resolved is why Visual Studio .NET 2003 "at school" rounded to 57405, which may be due to the compiler representing the double differently to the other compilers, but that sounds unlikely.
Since Visual C++ compiled it the same way as g+, I'm now thinking that I may have fudged my testing, as I was in a hurry. I'll look more into it tomorrow when I go back, run more code and see for sure.
Reply With Quote
  #12  
Old 25th August 2009, 03:57 PM
David Becker Offline
Registered User
 
Join Date: Feb 2006
Posts: 780
linuxfedorafirefox
Quote:
Originally Posted by Gödel View Post
sorry

The thing that has not been resolved is why Visual Studio .NET 2003 "at school" rounded to 57405, which may be due to the compiler representing the double differently to the other compilers, but that sounds unlikely.
Were the results different than on another platform using the same compiler?

Anyway:

3.9.1-8

... The value representation of floating-point types is implementation-defined. ...

David
Reply With Quote
  #13  
Old 25th August 2009, 06:27 PM
David Becker Offline
Registered User
 
Join Date: Feb 2006
Posts: 780
linuxfedorafirefox
Here's a better explanation:

http://en.wikipedia.org/wiki/Floatin...n_and_rounding

"Whether or not a rational number has a terminating expansion depends on the base. ... "

David
Reply With Quote
  #14  
Old 25th August 2009, 08:36 PM
Gödel's Avatar
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,095
windows_vistaie
The irony is that 57405 can be represented exactly by a double, at least with gcc, you can see that by running the following code:

Code:
#include <iostream>
using namespace std;
int main()
{
     double n=574.05*100;

     cout.precision(18);
     cout<<"n = 574.05*100 = "<<n<<endl;
     cout<<"(int)n = "<<(int)n<<endl;
     (*(long long*)&n)++;
     cout<<"next double is "<<n<<endl;
     cout<<"(int)n = "<<(int)n<<endl;
     (*(long long*)&n)++;
     cout<<"next double is "<<n<<endl;
     cout<<"(int)n = "<<(int)n<<endl;
     return 0;
}
Code:
$ g++ -o gcctest gcctest.cpp -Wall
$ ./gcctest
n = 574.05*100 = 57404.9999999999927
(int)n = 57404
next double is 57405
(int)n = 57405
next double is 57405.0000000000073
(int)n = 57405
The successive doubles are obtained by reinterpreting the 64bit pattern for a double as a 64bit int (long long) and incrementing by 1 (bit), see http://www.cygnus-software.com/paper...ringfloats.htm

So maybe the .NET 2003 compiler does some clever trickery to make the answer exact when necessary (which sounds unlikely)
Reply With Quote
  #15  
Old 25th August 2009, 08:52 PM
David Becker Offline
Registered User
 
Join Date: Feb 2006
Posts: 780
linuxfedorafirefox
Quote:
Originally Posted by Gödel View Post
The irony is that 57405 can be represented exactly by a double...
That's not the issue.

Quote:
Originally Posted by Gödel View Post
Code:
// ...
     double n=574.05*100; // ...
The literal 574.05 can be represented exactly in base-10, as we clearly see. This is interpreted as a double, before multiplying by 100. While interpreting as a double it goes to base-2 encoding which can't exactly represent the 0.05 part since 0.05 equals 1/20 while 20 is not a (whole) power of 2.

From aforementioned wiki page: "In base-2 only rationals with denominators that are powers of 2 (such as 1/2 or 3/16) are terminating."

David
Reply With Quote
Reply

Tags
converting, double, int, trouble

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
FC6 CPU double what is actually installed jin01 Hardware & Laptops 3 15th September 2007 01:51 AM
How to get rid of the double cursors in xen newbie2006 Using Fedora 1 12th February 2007 10:26 AM
Double posting giulix Suggestions & Feedback 3 13th January 2006 01:01 PM
freezing during screensaver and trouble on reboot + gnome panel trouble bwalsh Using Fedora 0 5th July 2005 02:45 AM


Current GMT-time: 21:04 (Friday, 24-05-2013)

TopSubscribe to XML RSS for all Threads in all ForumsFedoraForumDotOrg Archive
logo

All trademarks, and forum posts in this site are property of their respective owner(s).
FedoraForum.org is privately owned and is not directly sponsored by the Fedora Project or Red Hat, Inc.

Privacy Policy | Term of Use | Posting Guidelines | Archive | Contact Us | Founding Members

Powered by vBulletin® Copyright ©2000 - 2012, vBulletin Solutions, Inc.

FedoraForum is Powered by RedHat