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

64 vs 32 bit double parsing issue with the round-trip format specifier "R"

我在 .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?

更新 这有效,并为 ToString("G6"):

产生不同的输出
[Fact]
public void ParseText()
{
    var numText = "51.580133";
    double.Parse(numText)
        .ToString("G8")
        .Should().Be(numText);
}

我从微软发现了这个有趣的观点,它可以解释这个问题

In some cases, Double values formatted with the "R" standard numeric format string do not successfully round-trip if compiled using the /platform:x64 or /platform:anycpu switches and run on 64-bit systems.

To work around this problem, you can format Double values by using the "G17" standard numeric format string. The following example uses the "R" format string with a Double value that does not round-trip successfully, and also uses the "G17" format string to successfully round-trip the original value.

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