Precision of Floating-Point Data Types - Test

This section describes testing results of precision comparison on floating-point data types: 'float', 'double', and 'decimal'

If you run the tutorial example presented in the previous section, you will get this output:

```Testing 1/3:
f = 0.3333333
d = 0.333333333333333
m = 0.3333333333333333333333333333
f*3 = 1
d*3 = 1
m*3 = 0.9999999999999999999999999999
(double)f*3 = 1.00000002980232
(decimal)f*3 = 0.9999999
(decimal)d*3 = 0.999999999999999
(double)((float)i/3)*3 = 1
Testing 2/3:
f = 0.6666667
d = 0.666666666666667
m = 0.6666666666666666666666666667
f*3 = 2
d*3 = 2
m*3 = 2.0000000000000000000000000001
(double)f*3 = 2.00000005960464
(decimal)f*3 = 2.0000001
(decimal)d*3 = 2.000000000000001
(double)((float)i/3)*3 = 2
```

Question 1: Why ((float)1/3)*3 = 1?

Don't try to answer it with the possibility that the compiler is smart, and optimizes (/3)*3 as *1. I have tried to get the /3 part from a variable like as shown in this example program, from a method, or even from another class that compiled separately. They all give me the same result.

I believe that the answer is related to the storage algorithm of floating-point data types. But I don't have time to figure it out yet.

Question 2: If ((float)1/3)*3 = 1, then why ((decimal)1/3)*3 = 0.9999999999999999999999999999?

I also don't have a clear answer yet. But I believe that the answer is also related to the storage algorithm of floating-point data types.

No matter what the answer is, this behavior is telling us that "decimal" is not a natural extension of "float", like "double" extending "float".

If you are a designer, don't ask your developers to change "double" to "decimal" immediately. Do some experiments first.

Question 3: If ((float)1/3)*3 = 1, and ((decimal)1/3)*3 < 1, then is the float type more accurate that the decimal type?

I will leave this question to you to answer.

Question 4: If f is (float)1/3 = 0.3333333, then why (double)f*3 = 1.00000002980232?

I am expecting (double)f*3 = 0.9999999, because casting f into "double" will force the expression to be evaluated in double precision, giving 0.9999999. What do you think?

Question 5: If (double)f*3 = 1.00000002980232, why (double)((float)1/3)*3 = 1?

The difference here is that (float)1/3 is evaluated first and stored in a variable f.

My guess to what happened here is that all floating data expressions are evaluated in double precision. What do you think?

Last update: 2015.