1

I'm attempting to truncate a series of double-precision values in C#. The following value fails no matter what rounding method I use. What is wrong with this value that causes both of these methods to fail? Why does even Math.Round fail to correctly truncate the number? What method can be used instead to correctly truncate such values?

The value :

double value = 0.61740451388888251;

Method 1:

return Math.Round(value, digits);

Method 2:

double multiplier = Math.Pow(10, decimals)
return Math.Round(value * multiplier) / multiplier;

Fails even in VS watch window!

round

Robin Rodricks
  • 110,798
  • 141
  • 398
  • 607

4 Answers4

5

Double is a floating binary point type. They are represented in binary system (like 11010.00110). When double is presented in decimal system it is only an approximation as not all binary numbers have exact representation in decimal system. Try for example this operation:

double d = 3.65d + 0.05d;

It will not result in 3.7 but in 3.6999999999999997. It is because the variable contains a closest available double.

The same happens in your case. Your variable contains closest available double.

For precise operations double/float is not the most fortunate choice. Use double/float when you need fast performance or you want to operate on larger range of numbers, but where high precision is not required. For instance, it is perfect type for calculations in physics. For precise decimal operations use, well, decimal.

Here is an article about float/decimal: http://csharpindepth.com/Articles/General/FloatingPoint.aspx

PiotrWolkowski
  • 8,408
  • 6
  • 48
  • 68
3

According to this online tool which gives the binary representation of doubles, the two closest double values to 0.62 are:

6.19999999999999995559107901499E-1 or 0x3FE3D70A3D70A3D7 link

6.20000000000000106581410364015E-1 or 0x3FE3D70A3D70A3D8 link

I'm not sure why neither of these agree with your value exactly, but like the others said, it is likely a floating point representation issue.

eigenchris
  • 5,791
  • 2
  • 21
  • 30
3

If you need a more exact representation of the number you might have to use the decimal type, which has more precision but smaller range (it's usually used financial calculations).

More info on when to use each here: https://stackoverflow.com/a/618596/1373170

Community
  • 1
  • 1
Pablo Romeo
  • 11,298
  • 2
  • 30
  • 58
-1

I think you are running up against the binary limit of a double-precision float (64 bits). From http://en.wikipedia.org/wiki/Double-precision_floating-point_format, a double only gives between 15-17 significant digits.

ryanyuyu
  • 6,366
  • 10
  • 48
  • 53