我们说我们有以下简单的代码
string number = "93389.429999999993";
double numberAsDouble = Convert.ToDouble(number);
Console.WriteLine(numberAsDouble);
之后,转化numberAsDouble
变量的值为93389.43。我该怎么做才能使这个变量保持完整的数字而不是四舍五入呢?我发现Convert.ToDecimal
的行为方式不同,但我需要将值设为double。
-------------------小更新---------------------
在上面代码的第2行中放置一个断点,表明numberAsDouble变量在控制台中显示之前具有舍入值93389.43。
答案 0 :(得分:11)
93389.429999999993
无法将完全表示为64位浮点数。 double
只能容纳15或16位数字,而您有17位数字。如果您需要这种精确度,请改用decimal
。
(我知道你说你需要它是双重的,但如果你能解释原因,可能会有替代解决方案)
答案 1 :(得分:6)
这是预期的行为。
双重不能完全代表每个数字。这与字符串转换无关。
您可以自己查看:
Console.WriteLine(93389.429999999993);
这将打印93389.43
。
以下内容也表明了这一点:
Console.WriteLine(93389.429999999993 == 93389.43);
这会打印True
。
答案 2 :(得分:4)
请注意,此处有两次转化。首先,您将字符串转换为double,然后将该双重转换回字符串以显示它。
您还需要考虑double
没有无限精度;根据字符串的不同,某些数据可能会丢失,因为double不具备存储它的能力。
当转换为双倍时,它不会进入" round"不仅仅是必须的。考虑到double的功能,它将创建最接近所提供数字的双精度。将该双倍转换为字符串时,更有可能保留某些信息。
答案 3 :(得分:3)
请参阅以下内容(特别是Michael Borgwardt答案的第一部分):
decimal vs double! - Which one should I use and when?
双倍并不总是保持精确度,具体取决于您尝试转换的数字
如果您需要精确,则需要使用decimal
答案 4 :(得分:0)
double
类型的有限精度为64位,因此当实数存储在numberAsDouble变量中时会发生舍入错误。
适用于您的示例的解决方案是使用decimal
类型,它具有128位精度。然而,同样的问题出现了较小的差异。
对于任意大数字,.NET Framework 4.0中的System.Numerics.BigInteger
对象支持整数的任意精度。但是,您需要第三方库来使用任意大的实数。