我试图了解浮点不准确以及如何在c#中处理它们。
我看过Floating point inaccuracy examples给出了一些很好的答案,但我想特别了解c#。
使用小数“8.8”,如何将其转换为二进制表示形式然后再转换为十进制,以便该值更改为“8.8000000000000007”?
我尝试过使用How to get the IEEE 754 binary representation of a float in C#的建议但没有运气。
答案 0 :(得分:3)
但事情是这样的:8.8000000000000007也无法在double
中准确表示。最接近的值是8.800000000000000710542735760100185871124267578125(我从Jon Skeet的DoubleConverter获得)。然后,您可以对该字符串使用Decimal.Parse
以获得小数值8.80000000000000071054273576。
decimal d = 8.8M;
double dbl = (double)d;
string s = DoubleConverter.ToExactString(dbl);
decimal dnew = decimal.Parse(s);
答案 1 :(得分:0)
您可以比较一些不同的双打:
double a = BitConverter.ToDouble(new byte[] { 156, 153, 153, 153, 153, 153, 33, 64, }, 0);
double b = BitConverter.ToDouble(new byte[] { 155, 153, 153, 153, 153, 153, 33, 64, }, 0);
double c = BitConverter.ToDouble(new byte[] { 154, 153, 153, 153, 153, 153, 33, 64, }, 0);
double d = BitConverter.ToDouble(new byte[] { 153, 153, 153, 153, 153, 153, 33, 64, }, 0);
double e = BitConverter.ToDouble(new byte[] { 152, 153, 153, 153, 153, 153, 33, 64, }, 0);
Console.WriteLine(a.ToString("R"));
Console.WriteLine(b.ToString("R"));
Console.WriteLine(c.ToString("R"));
Console.WriteLine(d.ToString("R"));
Console.WriteLine(e.ToString("R"));
使用format string "R"
会显示额外的数字,但仅在必要时才能区分其他可表示的System.Double
。
添加(explanation of the bytes):64
和33
给出数字8.8
的符号,幅度和第一(最)有效位。由于8.8
是一个小分母(44/5中的5)的分数,所以其余的比特在短时间内反复重复也就不足为奇了。为了得到准确的8.8
,153s必须永远持续下去。但是double
中只有八个字节的空间。因此我们需要回合。舍入到154
会得到最接近的值,因为下一个“词语”(153
)更接近256
而不是0
。因此,c
是最精确的表示。
当您查看上述代码的输出时,即使我们使用c
格式字符串,您也会看到8.8
只是输出为"R"
。但是,您知道c
介于b
和d
之间(也在a
和e
之间),您可以从中轻松估算出“true”十进制值最接近8.8000000000000007
。