c#和浮点不准确

时间:2012-10-15 17:46:43

标签: c# floating-point ieee-754

我试图了解浮点不准确以及如何在c#中处理它们。

我看过Floating point inaccuracy examples给出了一些很好的答案,但我想特别了解c#。

使用小数“8.8”,如何将其转换为二进制表示形式然后再转换为十进制,以便该值更改为“8.8000000000000007”?

我尝试过使用How to get the IEEE 754 binary representation of a float in C#的建议但没有运气。

2 个答案:

答案 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):6433给出数字8.8的符号,幅度和第一(最)有效位。由于8.8是一个小分母(44/5中的5)的分数,所以其余的比特在短时间内反复重复也就不足为奇了。为了得到准确的8.8,153s必须永远持续下去。但是double中只有八个字节的空间。因此我们需要回合。舍入到154会得到最接近的值,因为下一个“词语”(153)更接近256而不是0。因此,c是最精确的表示。

当您查看上述代码的输出时,即使我们使用c格式字符串,您也会看到8.8只是输出为"R"。但是,您知道c介于bd之间(也在ae之间),您可以从中轻松估算出“true”十进制值最接近8.8000000000000007