TIP: Click on subject to list as thread! ANSI
echo: c_plusplus
to: CHRISTIAN FELDE
from: JONATHAN DE BOYNE POLLARD
date: 1997-11-10 15:26:00
subject: What`s wrong?

 CF> float pi;
 CF> [...]
 CF> cin >> pi;
 CF> [...]
 CF> if (pi != 3.142)
As I've said once already in this thread, floating point types in the C and 
C++ languages on most platforms, including PCs, use IEEE 754 format.  IEEE 
754 format is base *two*, not base ten.  
The important thing to remember is that it isn't true that a (fractional) 
number that has a finite number of digits in one base will have a finite 
number of digits in another.  The fraction 1/3, for example, has a finite 
representation in base 3 ("0.1"), but an infinitely recurring representation 
in base 10 ("0.3333333333333333333....").
The value 3.142 is a case in point.  It's binary expansion is infinitely 
long.  The IEEE 754 floating point formats Short Real, Long Real, and 
Extended Real (float, double, and long double in the C++ language on certain 
platforms) can therefore only hold an *approximation* to the value 3.142.  
Moreover, since Short Real only has 23 digits in its significand, whereas 
Long Real has 52, this approximation is going to be rounded to different 
numbers of binary places in the different floating point types.
This means that in your code, the float variable `pi' has the best 
approximation to 3.142 that can fit into a Short Real, whereas the literal 
value 3.142 in the `if' statement has the best approximation to 3.142 that 
can fit into a Long Real.  This is because in the C++ language floating point 
literals have, by default, the type `double'.
When your program comes to compare `pi', a float, and `3.142', a double, 
using the != operator it promotes them to the same type, promoting the  float 
to a double in this instance.  However, that does *not* magically produce a 
double-precision floating-point value that is the best approximation to 3.142 
that a double can hold -- because the float variable `pi' *didn't* hold 3.142 
in the first place, only an apprixmation to it that had 24 binary digits.  
The digits after the 24th that were "lost" when 3.142 was converted to Short 
Real for storing into the variable `pi' are lost for good.
Which, in turn, means that `pi' and 3.142 really *aren't* equal, since they 
actually contain two different floating-point numbers.
To get around this problem, eliminate the promotion in your code caused by 
the != operator.  You do this by using a *float* literal:
        if (pi != 3.142F)
[  Note for advanced programmers: This assumes, of course, that 
istream::operator>>(float&) and your compiler do the same thing when 
converting the string "3.142" to a `float' value.  Although this happens to 
be true of the vast majority of C++ implementations, it isn't always the 
case, nor is it required to be.  ]
 ¯ JdeBP ®
--- FleetStreet 1.19 NR
---------------
* Origin: JdeBP's point, using Squish (2:440/4.3)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.