CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2017
    Posts
    9

    Float point number simple arithmetic.

    Having such a simple `c` program:

    Code:
    #include <stdio.h>
        #include <float.h>
        
        int main( void ) {
        		float fl1 = 0.1;
        		
        		// Set precision to 24 bits
        		_control87(_PC_24, MCW_PC);
        
        		printf( "fl1: %.10f\n", fl1 );		
        		printf( "fl1*fl1: %.10f\n", fl1*fl1 );
        }
    and compiling it like that:

    Code:
    cl /W4 /Od /arch:IA32 teset1.c
    gives me:

    fl1: 0.1000000015
    fl1*fl1: 0.0100000007
    Can someone please explain me why does multiplying the `db1` variable returns

    0.0100000007
    instead of

    0.0100000003
    as expected?

    PS.

    I know that assigning the `0.1` value to the `float` makes it *truncated* from `double` to `float` but anyhow `0.1000000015 x 0.1000000015` results in **`0,01000000030000000225`** as I've checked in the *Windows Programmer Calculator*

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,109

    Re: Float point number simple arithmetic.

    Take your calculator and perform the following actions:
    1. convert decimal 0,1 to binary (OK, in HEX)
    2. truncate it to the max available length for the float
    3. multiply to itself
    4. convert the result to decimal

    What result will you get?
    Victor Nijegorodov

  3. #3
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,157

    Re: Float point number simple arithmetic.


  4. #4
    Join Date
    Feb 2017
    Posts
    632

    Re: Float point number simple arithmetic.

    Quote Originally Posted by Mulligan View Post
    Can someone please explain me why does multiplying the `db1` variable returns

    0.0100000007

    instead of

    0.0100000003

    as expected?
    A single-precision FP has 6-7 significant decimal digits, and a double-precision FP has 15-18. A good rule is to consider the significant digits only. The range of significant digits in an FP starts with the first non-zero digit to the left and stretches to the right a certain number of digits determined by the precision.

    In your example, the 7 of 0.0100000007 is in a non-significant position of a single-precision FP, whereas the 3 of 0.0100000003 is in a significant position of a double-precision (*) FP. It means you can trust the 3, but not the 7. The 7, most likely, has appeared as a result of truncations and roundings rather than proper arithmetic operations.

    This significant-digit rule is fine for the everyday use of FP numbers. It avoids a lot of head-scratching over the intricacies of the FP standard. But it is, of course, never wrong to study FP in depth.

    (*) Supposedly, the "Windows Programmer Calculator" works with double precision (at least).
    Last edited by wolle; Yesterday at 03:19 AM.

  5. #5
    Join Date
    Feb 2017
    Posts
    632

    Re: Float point number simple arithmetic.

    In addition to my post #4.

    Not all decimal numbers have a finite digital representation. This includes 0.1, which requires an infinite number of bits. So when you assign 0.1 to a single-precision FP, there is a truncation error. When you print the FP, you see 0.1000000015, where the 15 is the error. The 15, however, is not part of the significant-digit range and should not be considered. (If you instead assign 0.125, there is no truncation because it has a finite digital representation that fits within the significant-digit range.)

    Now say you assign 0.1000000015 to a double-precision FP. This is a different story because now the 15 is part of the significant-digit range of the FP. If you square this FP, a 3 appears at a certain position determined by the place of the 15. If you instead square 0.1015, the 3 shows up again but in another position. This happens both with single and double precision. It is because 0.1015 is within the significant-digit range of both, as is the 3 in the squared result.
    Last edited by wolle; Yesterday at 01:24 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured