2

If I have the following code (this was written in .NET)

double i = 0.1 + 0.1 + 0.1;

Why doesn't i equal 0.3?
Any ideas?

Sam Saffron
132k81 gold badges334 silver badges511 bronze badges
asked Oct 23, 2008 at 7:07
1
  • This is not specific to .NET by the way, Float and Double based in binary have this problem for many decimal values converted to binary. Commented Oct 23, 2008 at 7:20

7 Answers 7

6

You need to read up on floating point numbers. Many decimal numbers don't have an exact representation in binary so they won't be an exact match.

That's why in comparisons, you tend to see:

if (abs(a-b) < epsilon) { ...

where epsilon is a small value such as 0.00000001, depending on the accuracy required.

answered Oct 23, 2008 at 7:10
Sign up to request clarification or add additional context in comments.

Comments

3

Double is a 64-bit floating point data type. It stores decimals as approximate values. If you need exact values, use the Decimal data type which is a Binary Coded Decimal data type.

answered Oct 23, 2008 at 7:10

1 Comment

Some fractional values are not approximate in binary (like 1/2, or 1/4 or 3/4), just many numbers in base ten (like 0.1, 0.3) get approximated when converted to base two.
1

The precision of floating point arithmetic cannot be guaranteed.

answered Oct 23, 2008 at 7:09

1 Comment

It can and is guaranteed in many systems - but it's guaranteeing a certain level of precision rather than perfection (which is unattainable here, as neither 0.1 nor 0.3 can be exactly represented in binary floating point).
1

Equality with floating point numbers is often not used because there is always an issue with the representation. Normally we compare the difference between two floats and if it is smaller than a certain value (for example 0.0000001) it is considdered equal.

answered Oct 23, 2008 at 7:11

Comments

1

Double calculation is not exact. You have two solution:

  • Use the Decimal type which is exact
  • compare abs(i - 0.3) < espilon
answered Oct 23, 2008 at 7:11

4 Comments

Decimal is not "exact" - it just has a different representation, that happens to work better with typical decimal values - i.e. base-10 rounding. That doesn't make it "exact".
Having never used .NET, in what sense is Decimal not exact? Do you mean such things as sqrt(2) and pi or are there actually decimal values (I mean any base-10 number with finite number of digits) that can't be represented by it?
Doing arithmetic on things with different scales (i.e. add a very large number and a very small number) would be a trivial example - but just things like "divide by 3" then "multiply by 3" should be enough to not count as "exact".
@paxdiablo, decimal is not "exact", but it is much more what-you-see-is-what-you-get than double is, because what you usually look at is the string representation of the number, and for decimal it is almost obvious what the underlying "internal" value is, given the string representation. I invite you to look at these decimal expressions (using C# syntax here): 25d / 3d and (25d / 3d) * 3d and 22d / 3d and (22d / 3d) * 3d.
1

Jon Skeet has a very good walkthrough of this here, and the same for decimal here.

answered Oct 23, 2008 at 7:18

Comments

0
answered Oct 23, 2008 at 7:25

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.