我试图了解浮点不准确性以及如何在 c# 中处理它们。
我查看了浮点不准确示例,它给出了一些很好的答案,但我想专门针对 c# 来理解它。
使用十进制“8.8”,我如何将其转换为二进制表示,然后再转换回十进制,以便该值更改为“8.8000000000000007”?
我尝试使用How to get the IEEE 754 binary representation of a float in C# 中的建议,但没有运气。
我试图了解浮点不准确性以及如何在 c# 中处理它们。
我查看了浮点不准确示例,它给出了一些很好的答案,但我想专门针对 c# 来理解它。
使用十进制“8.8”,我如何将其转换为二进制表示,然后再转换回十进制,以便该值更改为“8.8000000000000007”?
我尝试使用How to get the IEEE 754 binary representation of a float in C# 中的建议,但没有运气。
不过,事情是这样的: 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);
您可以像这样比较一些不同的双打:
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"));
使用格式字符串 "R"
显示额外的数字,但仅在需要区分其他可表示System.Double
的 .
加法(字节的解释):64
并33
给出数字的符号、大小和第一个(最高)有效位8.8
。由于8.8
是一个分母很小的分数(44/5 中的 5),因此其余位在很短的时间内一遍又一遍地重复也就不足为奇了。准确地说8.8
,153s 必须永远持续下去。但是 . 文件中只有八个字节的空间double
。因此我们需要四舍五入。四舍五入154
给出最接近的值,因为下一个“项” ( )比153
更接近。因此是最精确的表示。256
0
c
当您查看上述代码的输出时,您会发现即使我们使用了格式字符串,它c
也只是输出。但是您知道它介于and之间(也介于and之间),从中您可以轻松估计“真实”十进制值最接近。8.8
"R"
c
b
d
a
e
8.8000000000000007