【问题标题】:Double type strange behavior while concatenating with String or Converting to String与字符串连接或转换为字符串时的双重类型奇怪行为
【发布时间】:2015-01-26 17:44:20
【问题描述】:

我在项目中具有比较对象值并显示差异的日志记录功能,但我有一个场景,我有双精度数据类型的纬度和经度值,但是当我将它与字符串连接或将其转换为字符串时,我得到了奇怪的行为,因为它在两个变量中显示相同的值,这是完全无法理解的。

代码如下:

double value1 = -6.2845230102539063;
double value2 = -6.2845230102539098;
        if (!object.Equals(value1, value2))
        {
            var result = value2 + " to " + value1;
            Console.WriteLine(result);
        }

        Console.ReadLine();

预期输出:

-6.2845230102539098 到 -6.2845230102539063

实际输出:

-6.28452301025391 到 -6.28452301025391

这里是DEMO FIDDLE

https://dotnetfiddle.net/0XM3Da

这里发生了什么?

【问题讨论】:

  • 值刚刚结束可能是由于 var 的大小限制!
  • 是的,它看起来像精度问题,但我不确定,因为它支持 16 位精度

标签: c# string double tostring string-concatenation


【解决方案1】:

这在@LukeH 的answer 中针对“C# 中输出的格式化双精度数”进行了说明:

问题是 .NET 将始终将 double 舍入到 15 位有效 小数位之前应用您的格式,无论 您的格式要求的精度,无论精确的小数如何 二进制数的值。

使用该答案中链接到的 DoubleConverter 类,我们得到

var x = -6.2845230102539063;
var y = -6.2845230102539098;

Console.WriteLine(x == y);
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(DoubleConverter.ToExactString(x));
Console.WriteLine(DoubleConverter.ToExactString(y));

打印出来的

False
-6.28452301025391
-6.28452301025391
-6.28452301025390625
-6.284523010253909802713678800500929355621337890625

或者你可以使用G17格式规范

Console.WriteLine(x.ToString("G17"));
Console.WriteLine(y.ToString("G17"));

这会给你

-6.2845230102539063
-6.2845230102539098

【讨论】:

    【解决方案2】:

    来自 MSDN:http://msdn.microsoft.com/en-us/library/678hzkk9.aspx

    Double 的精度为 15-16 位。你已经超过了这个限制。 您应该使用 Decimal。 请参阅此处了解详细信息:Can C# store more precise data than doubles?

    【讨论】:

    • 这个答案并不完全准确,因为value1 != value2
    【解决方案3】:

    您是否尝试过十进制数据类型。它为您提供了数字的准确表示……我想是针对银行和股票市场的。您可以将尾数减少到一定长度(可能是 18)。

    【讨论】:

      【解决方案4】:

      一个Double值最多有15位小数精度,可以参考详细解释http://msdn.microsoft.com/zh-cn/library/system.double(v=vs.110).aspx

      【讨论】:

        【解决方案5】:

        发件人:http://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx

        '默认情况下,返回值仅包含 15 位精度,但内部维护最多 17 位。'

        所以它知道它们的大小不同,但不会那样显示。

        【讨论】:

        • 当我调试和检查时显示正确,但连接时显示奇怪
        猜你喜欢
        • 2020-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-24
        相关资源
        最近更新 更多