Why does Convert.ToDecimal(Double) round to 15 sig

2019-05-11 07:26发布

I have a double with 17 digits after the decimal point, i.e.:

double myDouble = 0.12345678901234567;

If I convert this to a decimal like this:

decimal myDecimal = Convert.ToDecimal(myDouble);

then the value of myDecimal is rounded, as per the Convert.ToDecimal documentation, to 15 digits (i.e. 0.0123456789012345). My question is, why is this rounding performed?

I understand that if my original number could be accurately represented in base 10 and I was trying to store it as a double, then we could only have confidence in the first 15 digits. The final two digits would be subject to rounding error. But, that's a base 10 biased point of view. My number may be more accurately represented by a double and I wish to convert it to decimal while preserving as much accuracy as possible.

Shouldn't Convert.ToDecimal aim to minimise the difference between myDouble and (double)Convert.ToDecimal(myDouble)?

4条回答
We Are One
2楼-- · 2019-05-11 08:03

Every terminating binary fraction is exactly representable as a decimal fraction, so the minimum possible difference for a finite number is always 0. The IEEE 754 64-bit representation of your number is exactly equal to 0.1234567890123456634920984242853592149913311004638671875

Every conversion from binary floating point to decimal or decimal string must embody some decision about rounding. In theory, they could preserve all the digits, but that would result in some very long outputs with most of the digits having little meaning.

One option, used in Java's Double.toString, is to stop at the shortest decimal representation that would convert back to the original double.

Most set some fairly arbitrary limit. 15 significant digits preserves most meaningful digits.

查看更多
smile是对你的礼貌
3楼-- · 2019-05-11 08:08

From the documentation of Double:

A Double value has up to 15 decimal digits of precision, although a maximum of 17 digits is maintained internally

So, as the double value itself has a maximum of 15 decimal places, converting it to Decimal will result in a Decimal value with 15 significant figures.

查看更多
你好瞎i
4楼-- · 2019-05-11 08:25

The behavior of the rounding guarantees that conversion of any Decimal which has at most fifteen significant figures to double and back to Decimal will yield the original value unchanged. If values were rounded to sixteen figures rather than fifteen, such a guarantee would not only fail to hold for number with sixteen figures, but it wouldn't even hold for much shorter values. For example, the closest Double value to 9000.04 is approximately 9000.040000000000873115; rounding that to sixteen figures would yield 9000.040000000001.

The choice of rounding one should use depends upon whether regards the best Decimal value of double value 9000.04 as being 9000.04m, 9000.040000000001m, 9000.0400000000008731m, or perhaps something else. Microsoft probably decided that any representation other than 9000.04m would be confusing.

查看更多
Anthone
5楼-- · 2019-05-11 08:30

The following is from the documentation of the method in question.

http://msdn.microsoft.com/en-us/library/a69w9ca0(v=vs.110).aspx

"The Decimal value returned by this method contains a maximum of 15 significant digits. If the value parameter contains more than 15 significant digits, it is rounded using rounding to nearest.

查看更多
登录 后发表回答