Thursday, November 13, 2014

0.1 Float > 0.1 Double ?

  • Introduction:


You should not worry about using all comparison operators with floating-point numbers (float, double, and decimal). The ==, <, >, <=, >=, and != operators work just fine with these numbers. But, it is important to remember that they are floating-point numbers, rather than real numbers or rational numbers or any other such thing.

In pure (real) math, every decimal has an equivalent binary. In floating-point math, this is just not true! Consider the following example, let:
double d = 0.1;
float f = 0.1;
, should the expression f > d return true or false? Let’s analyze the answer to this question during the remaining part of this article.
  • 0.1 in Binary:

Many new programmers become aware of binary floating-point after seeing their programs give odd results:
“Why does my program print 0.10000000000000001 when I enter 0.1?”
“Why does 0.3 + 0.6 = 0.89999999999999991?”
“Why does 6 * 0.1 not equal 0.6?”
The answer is that most decimals have infinite representations in binary. Take 0.1 for example. It’s one of the simplest decimals you can think of, and yet it looks so complicated in binary:

Decimal 0.1 In Binary ( To 1369 Places) - Photo by [2]
The bits go on forever; no matter how many of those bits you store in a computer, you will never end up with the binary equivalent of decimal 0.1.
0.1 is one-tenth, or 1/10. To show it in binary, divide binary 1 by binary 1010, using binary long division:
Computing One-Tenth In Binary - Photo by [2]

The division process would repeat forever because 100 re-appear as the working portion of the dividend. Recognizing this, we can abort the division and write the answer in repeating bicimal notation, as 0.00011.
When working with floating-point numbers, it is important to remember that they are floating-point numbers, rather than real numbers or rational numbers or any other such thing. You have to take into account their properties and not the properties everyone wants them to have. Do this and you automatically avoid most of the commonly-cited "pitfalls" of working with floating-point numbers.
  • Floating Binary Point Types :

Float and Double are floating binary point types. In other words, they represent a number like this: 10001.10010110011.
Decimal is a floating decimal point type. In other words, they represent a number like this: 12345.65789.

Precision is the main difference: Float is 7 digits (32 bit), Double is 15:16 digits (64 bit), and Decimal is 28:29 significant digits (128 bit).
Decimals have much higher precision and are usually used within financial applications that require a high degree of accuracy. Decimals are much slower (up to 20X times in some tests [4]) than a double/float. Decimals versus Floats/Doubles cannot be compared without a cast whereas Floats versus Doubles can.
  • Question Answer :

As 0.1 cannot be perfectly represented in binary, while double has 15 to 16 decimal digits of precision, and float has only 7. So, they both are less than 0.1.
I'd say the answer depends on the rounding mode when converting the double to float. float has 24 binary bits of precision, and double has 53.
In binary, 0.1 is:
0.1₁₀ = 0.0001100110011001100110011001100110011001100110011…₂
            ^        ^         ^   ^
            1       10        20  24

So if we round up at the 24th digit, we'll get:
0.1₁₀ ~ 0.000110011001100110011001101
            ^        ^         ^   ^
            1       10        20  24

, which is greater than both of the exact value and the more precise approximation at 53 digits.
So, yes 0.1 float is greater than 0.1 double. This expression returns true! 
  • Examples :

It’s important to note that some decimals with terminating bicimals don’t exist in floating-point either. This happens when there are more bits than the precision allows for. For example,
0.500000000000000166533453693773481063544750213623046875
converts to :
0.100000000000000000000000000000000000000000000000000011
, but that’s 54 bits. Rounded to 53 bits it becomes :
0.1000000000000000000000000000000000000000000000000001
, which in decimal is :
0.5000000000000002220446049250313080847263336181640625.
Such precisely specified numbers are not likely to be used in real programs, so this is not an issue that’s likely to come up.

Interesting fact: 1/3 is a repeating decimal = 0.333333333333333333333……....
But in Ternary (The base-3 numeral system) it’s only 0.1 !

____________________________________________________________________

References: