C# 浮点戏剧性错误(小数部分完全丢失)
我得到了C# 浮点戏剧性错误(小数部分完全丢失),c#,precision,floating-accuracy,C#,Precision,Floating Accuracy,我得到了商==14385472(完全不是真实值:14385471333…)。它完全失去了所有的分数部分 我知道浮点计算的不准确性(似乎不是我应该知道的全部),但是,正如我所知,错误可能出现在更远的有效数字上。但这里的红利只有8位数。为什么会发生如此戏剧性的错误 可选子问题:我应该记住什么规则来预见未来的此类错误 请注意:将divident的类型从float改为double可以解决此问题。的精度为6-9位。您的价值太大,无法在没有损失的情况下放入浮动 double的精度约为15-17位 例如,检查
商
==14385472(完全不是真实值:14385471333…)。它完全失去了所有的分数部分
我知道浮点计算的不准确性(似乎不是我应该知道的全部),但是,正如我所知,错误可能出现在更远的有效数字上。但这里的红利只有8位数。为什么会发生如此戏剧性的错误
可选子问题:我应该记住什么规则来预见未来的此类错误
请注意:将divident的类型从float改为double可以解决此问题。的精度为6-9位。您的价值太大,无法在没有损失的情况下放入浮动
double的精度约为15-17位
例如,检查(int)43156414f
或(double)43156414f
的值-它们都是43156416,float
(Single
)使用23位作为尾数
所以float
可以表示高达2**24-1==16777215
的整数,这接近14385471
。
我们的可能性是:
quotient = 43156414f / 3;
所以我们可以看到,我们只有14385471f
和14385472f
可供选择;如果浮动
,则没有放置14385471.33333 F的位置。
让我们看看
01001011 01011011 10000001 00111111 correponds to 14385471f (let's add 1 bit)
01001011 01011011 10000001 01000000 correponds to 14385472f
我们要
float x = 14385471.3333333333f;
byte[] data = BitConverter.GetBytes(x);
Console.Write(" ", string.Join(" ", data
.Reverse()
.Select(b => Convert.ToString(b, 2).PadLeft(8, '0'))));
它对应于14385471f
。我们还有更多的问题
01001011 01011011 10000001 00111111
现在,43156414f>2**24-1(16777215)
和43156414f
不能表示为float
quotient = 43156414f / 3;
因此,商
的实际值为
01001100 00100100 10100000 11110000 corresponds to 43156416
最后,如果您想要14385471.33
,单次
是不够的,请尝试double
:
43156416 / 3 == 14385472
使用十进制类型,它可以容纳比float更大的值,并且不会因为某种原因而失去预知力,因为我的头脑中有“类似12位数的感知”。显然,我把事情搞砸了。非常感谢。
// 14385471.333333334
double quotient = 43156414d / 3;