-
November 23rd, 2021, 12:38 PM
#1
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
instead of
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*
-
November 23rd, 2021, 01:39 PM
#2
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
-
November 25th, 2021, 01:43 PM
#3
Re: Float point number simple arithmetic.
-
November 29th, 2021, 12:23 AM
#4
Re: Float point number simple arithmetic.
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.
-
November 29th, 2021, 03:48 AM
#5
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; December 1st, 2021 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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|