double to int conversion leads to crazy results

llewelly@198.dsl.xmission.com llewelly@198.dsl.xmission.com
Fri Dec 31 20:54:00 GMT 1999


The cout function that prints a double rounds.

static_cast<int>(some_double) truncates.

Floating point arithetic is *not* exact; in particular, some constants    
  (such as 2.03) cannot be exactly represented in the 64 bit IEEE 
  double precision floating point standard, which gcc uses to represent   
  doubles.

  This is due to the fact that 2.03 is a base 10 floating point  
    value, while doubles are represented as base 2 floating point values.

So you start with an imprecise value for 2.03, and this imprecision
  gets larger each time you multiply by 10.

Eventually, you end up with a value that is just a tiny bit smaller
  (say, by 2^-50 or so) than 2030.

static_cast<int> truncates this to 2029, since that is the next int
  lower than 2030 minus a small epsilon.

The operator<<() that cout uses, however, rounds - and rounds it up
  because the fraction is >=0.5 .

On Mon, 20 Dec 1999, Markus Werle wrote:

> // Maybe I am too tired today, but look at that output:
> //  > g++ --version
> // 2.95.2
> 
> // > uname -a
> // Linux aachen 2.2.10 #12 Mon Nov 29 00:16:46 MET 1999 i586 unknown
> 
> // > g++ ConvertNumbersToStrings.C && a.out
> // static_cast<int>(0.203) = 0  
> // static_cast<int>(2.03) = 2   
> // static_cast<int>(20.3) = 20  
> // static_cast<int>(203) = 203  
> // static_cast<int>(2030) = 2030
> // static_cast<int>(2.03) = 2 
> // static_cast<int>(20.3) = 20
> // static_cast<int>(203) = 202
> // static_cast<int>(2030) = 2029           !!!!!!!!!!
> // static_cast<int>(20300) = 20299         !!!!!!!!!!
> // static_cast<int>(20.3) = 20      
> // static_cast<int>(203) = 203      
> // static_cast<int>(2030) = 2030    
> // static_cast<int>(20300) = 20300  
> // static_cast<int>(203000) = 203000
> 
> 
> // Here is the code:
> // ----------------------------------------------------------------------
> #include <iostream>
> 
> typedef double Double;
> 
> inline void Demonstrate (const Double& dd) {
>   Double d = dd;
>   for (int ii=0; ii < 5; ii += 1) {
>     cerr << "static_cast<int>(" << d << ") = " << flush
>    << static_cast<int>(d) << endl;
>     
>     d *= 10;
>   }
> }
> 
> 
> int main() {
>      Demonstrate(0.203);
>      Demonstrate(2.03);
>      Demonstrate(20.3);
> }
> 
> // ----------------------------------------------------------------------
> 

[snip]



More information about the Gcc-bugs mailing list