64与32位双解析问题与往返格式说明符" R"

时间:2017-07-28 12:22:42

标签: c# floating-point 64-bit floating-accuracy

我在.net(4.6.1)中有一个场景,解析6dp浮点值的字符串表示会在32位和64位模式下产生不同的结果。

[Fact]
public void ParseTest()
{
    var numText = "51.580133";
    double.Parse(numText)
        .ToString("R")
        .Should().Be(numText);
}

此测试以32位模式传递,但64位模式失败,因为生成的文本为:" 51.580132999999996"

我期望这样的舍入问题是通过等式导出的无理数或数字,但这里对浮点的长度和精度没有任何歧义。

这是在较旧的系统中,因此将所有内容更改为十进制将需要付出巨大的努力。

问题:

  1. 为什么会这样?
  2. 有哪些选项可以将此值可靠地舍入/截断为6dp?
  3. 更新 这样可以生成ToString的不同输出(" G6"):

    [Fact]
    public void ParseText()
    {
        var numText = "51.580133";
        double.Parse(numText)
            .ToString("G8")
            .Should().Be(numText);
    }
    

1 个答案:

答案 0 :(得分:5)

我从微软那里找到了一个有趣的观点,可以解释这个问题

  

在某些情况下,使用" R"格式化的Double值。标准数字   如果使用编译,则格式字符串不能成功往返   / platform:x64或/ platform:anycpu在64位系统上切换并运行。

     

要解决此问题,可以使用以下格式设置Double值的格式   " G17"标准数字格式字符串。以下示例使用   " R"格式字符串,其Double值不会往返   成功,并使用" G17"格式化字符串成功   往返原始价值。

评论和示例可以在这里找到:https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx