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