Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 浮点戏剧性错误(小数部分完全丢失)_C#_Precision_Floating Accuracy - Fatal编程技术网

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;