【问题标题】:Round double to 6th decimal place in C#在 C# 中将双精度舍入到小数点后 6 位
【发布时间】:2017-05-25 12:58:19
【问题描述】:

注意:我想声明,在提交我的问题之前,我已经做出了合理的努力,以自己和其他问题找到解决方案 - 但是我找到的解决方案不适合我的需求。

我正在使用的 API 返回一个带有 7 位小数的 double,例如: 1495120024.7705889

但是我需要将其打印(或返回一个字符串)为:1495120024.770589 - 基本上四舍五入到小数点后六位。

原本看似微不足道的事情,结果却令人费解。

这些是我尝试过的方法(假设上面的值存储在一个名为 d 的 double 中):

d.ToString() = 1495120024.77059

d.ToString("F6") = 1495120024.770590

d.ToString("F7") = 1495120024.7705900

Math.Round(d, 6) = 1495120024.7705891 - [舍入误差?]

Math.Truncate(d * 1000000) / 1000000 = 1495120024.7705879

Convert.ToDecimal(Math.Truncate(d * 1000000)) = 1495120024770590

Convert.ToDecimal(d) = 1495120024.77059

我知道这听起来很傻,但我需要将其四舍五入到小数点后六位并正确设置为字符串。我也知道双精度数的舍入错误,但遗憾的是我无法控制 API 返回的数据类型。

编辑 v1:

根据BWA 的评论,这是我想出的解决方案:

var s = Math.Round(d - Math.Truncate(d), 6).ToString(); s = s.Substring(s.IndexOf(".") + 1); s = $"{Math.Truncate(d)}.{s}";

但是hack这个词甚至还没有开始描述这个......

【问题讨论】:

  • 标记为 [rounding error] 的那个是合法的,确切的值是 1495120024.7705891132354736328125(这是你能找到的最接近的 1495120024.770589,因此也是输入double x = 1495120024.770589; 的实际结果)。我想它以这种方式打印有点烦人(它不是解析回值的最短字符串)。我不确定 F6 格式有什么问题
  • 只要我找到一种合适的方法将它转换为字符串然后可能会修剪掉它,我就会对那一点舍入错误很好。但即使是转换为字符串的行为也会把它搞砸:(
  • 浮点点,小数点位置不相关。 float 可存储 6 位有效数字,double 可存储 15 位有效数字。如果计算复杂,您将丢失数字。您只能看到 17 位数字,因为这是调试器用来将 binary 值转换为十进制的。四舍五入到 16 位只会误导任何人假设结果比它可能的更准确。它不会欺骗机器,最后一位数字只是随机噪声。提前满足您的需求的唯一方法是在 decimal 中完成所有数学运算,它可以存储 28 位数字。
  • 任何代码 sn-ps @HansPassant ?正如我所说,我收到的数据类型是双重的,我无法改变它。尝试转换为十进制也会破坏任何其他计算之前的数字。

标签: c# double rounding


【解决方案1】:
double d = 256.7705889;
Console.WriteLine(d.ToString("F6"));

256.770589

但是

double d = 1121111156.7705889;
Console.WriteLine(d.ToString("F6"));

写:

1121111156.770590

问题是 double 的工作原理。更多here

简短地说:之前的较长部分。 = 精度较低。

【讨论】:

  • 这并不能真正回答问题,因为您使用的是不同的值......但它确实给了我一个想法(又名。hack)......减少重要的位数只是为了获得正确的小数位,然后将字符串附加到原始截断的数字...
  • @ZuiqPazu 来自 API 的原始消息中的数字是多少?也许您需要捕获原始消息并手动解析十进制响应。
  • 数字各不相同,但有问题的是:1495120024.7705889 为双倍。
  • 所以也许只是从api中获取响应并手动解析它。如果你有字符串 1495120024.7705889 你可以把它解析成十进制。
  • 正如我所说,我从 API 收到了一个 double。我没有从字符串转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
相关资源
最近更新 更多