text: 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*
  #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 );
  }
  cl /W4 /Od /arch:IA32 teset1.c
  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
  
  Originally Posted by Mulligan
  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; December 1st, 2021 at 03:19 AM.
  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; December 1st, 2021 at 01:24.