【问题标题】:Convert float to double将浮点数转换为双精度
【发布时间】:2015-06-12 03:01:26
【问题描述】:

我正在尝试将Single 转换为Double,同时保持原始值。我找到了以下方法:

Single f = 5.2F;
Double d1 = f; // 5.19999980926514
Double d2 = Double.Parse(f.ToString()); // 5.2 (correct)

这种做法值得推荐吗?我不需要最佳方法,但必须将预期值传递给 double。将四舍五入的值存储在 double 中是否会产生后果?

【问题讨论】:

  • 并不是所有的浮点数都能准确表示,这就是为什么 5.2 变成 5.19999980926514。
  • 从二进制的角度来看,确实如此。 5.2 不能准确地表示为二进制浮点数,因此它可以为您提供最接近的值。
  • 我明白了,但是字符串转换不是一个大胆的举动吗?可以避免吗?
  • 你用这些数字在做什么?是的,将单转换为字符串并解析为双精度可能不是最好的方法。
  • @DStanley - 最好是硬编码,但我也可能不会假设。浮点逻辑是我绝对的恶习;我真正需要知道的是;如何将Single 转换为Double,同时在值确实是硬编码的情况下保持可表示性,因为值在某些时候被序列化。我想我明白直接将Single 转换为Double 是无害的,但这是一个演示问题。

标签: c# .net floating-point double


【解决方案1】:

您可以使用“十进制”代替字符串。

float f = 5.2F;
decimal dec = new decimal(f);//5.2
double d = (double)dec; //5.2

【讨论】:

    【解决方案2】:

    转换是准确的。所有Single 值都可以用Double 值表示,因为它们是以相同的方式“构建”的,只是具有更多可能的数字。你看到的 5.2F 实际上是5.1999998092651368。如果你去http://www.h-schmidt.net/FloatConverter/IEEE754.html 并插入 5.2,你会看到它的指数为 2^2(所以 4)和一个尾数1.2999999523162842。现在,如果将这两个数字相乘,您将得到 5.1999998092651368。

    Single 的最大精度为 7 digits,因此 .NET 仅显示 7 位数字。稍微四舍五入 5.1999998092651368 是 5.2

    【讨论】:

    • 5.1999998092651368 本身就是一个四舍五入的值。它不能精确地表示为二进制分数。最接近 5.2 的浮点数是 5.19999980926513671875。最接近 5.2 的双倍是 5.20000000000000017763568394002504646778106689453125
    【解决方案3】:

    如果您知道您的数字是 e.g. 的倍数0.01,我建议你转换成双精度数,四舍五入到最接近的整数,然后减去它以获得小数残差。将其乘以 100,四舍五入到最接近的整数,然后除以 100。将其与整数部分相加,得到最接近原始数字的 0.01 的倍数的 double 表示。

    请注意,根据float 值的原始来源,这种处理可能会或可能不会提高准确性。最接近 9000.02 的 float 值约为 9000.019531,最接近 9000.021 的 float 值约为 9000.021484f。如果这些值是通过将 9000.020 和 9000.021 转换为 float 得到的,那么它们之间的差应该是 0.01 左右。但是,如果它们是由例如到达的。计算9000f+0.019531f 和9000f+0.021484f,那么它们之间的差异应该更接近0.02。在减法之前四舍五入到最接近的 0.01 会在前一种情况下提高准确度,而在后一种情况下会降低准确度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-26
      • 1970-01-01
      • 2018-08-09
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      相关资源
      最近更新 更多