这里的,我不理解的代码部分:为什么划分结果会因演员阵容而异?
byte b1 = (byte)(64/0.8f); // b1 is 79
int b2 = (int)(64/0.8f); // b2 is 79
float fl = (64/0.8f); // fl is 80
为什么前两个计算关闭的一个?我应该如何执行这个操作,所以它的快速和正确?
编辑:我需要在字节
这里的,我不理解的代码部分:为什么划分结果会因演员阵容而异?
byte b1 = (byte)(64/0.8f); // b1 is 79
int b2 = (int)(64/0.8f); // b2 is 79
float fl = (64/0.8f); // fl is 80
为什么前两个计算关闭的一个?我应该如何执行这个操作,所以它的快速和正确?
编辑:我需要在字节
编辑:不完全正确,请参阅:Why does a division result differ based on the cast type? (Followup)
四舍五入问题:通过转换为字节/ INT,你剪辑的小数位。
但64/0.8
不应该导致任何小数位?错误:由于浮点数的性质,0.8f不能完全像内存中那样表示;它被存储为接近0.8f(但不完全)。见Floating point inaccuracy examples或类似的线程。因此,计算结果不是80.0f,而是79.xxx,其中xxx接近于1,但仍不完全为1。
您可以通过键入以下到即时窗口在Visual Studio中验证这一点:
(64/0.8f)
80.0
(64/0.8f) - 80
-0.0000011920929
100 * 0.8f - 80
0.0000011920929
您可以通过使用四舍五入解决这个问题:
byte b1 = (byte)(64/0.8f + 0.5f);
int b2 = (int)(64/0.8f + 0.5f);
float fl = (64/0.8f);
80.0f可以表示得很好。然而,0.8f不能,所以你实际上并没有得到80.0f。 – harold 2014-09-06 18:30:33
感谢您的追捕 - 我相应地解决了我的问题。 – Matthias 2014-09-06 18:36:13
请查看我的后续问题:http://stackoverflow.com/questions/25703864/why-does-a-division-result-differ-based-on-the-cast-type-followup我得到了二进制(64/0.8f)并反向工作,它确实等于80。 – ConditionRacer 2014-09-06 19:39:26
结果要理解这个问题,你需要了解浮点表示和操作的基本知识。
0.8f不能在内存中使用浮点数精确表示。
在数学中,64/0.8等于80 在浮点算术,60/0.8等于近似80
当你施放一个浮子的整数或一个字节,仅数的整数部分是保持。在你的情况下,浮点除法的不精确结果略小于80,因此转换为整数产生79.
如果你需要一个整数结果,我建议你四舍五入而不是转换结果。 一种方式来做到这一点是使用下面的函数,通过四舍五入到最接近的整数转换为整数:
Convert.ToInt32(64/0.8f);
恐怕快速和正确正处在这样的情况下胜算。
由于the underlying representation in our CPU architectures,二进制浮点运算几乎总是会产生小的错误。所以在你的初始表达式中,你实际上得到的值比数学上正确的值小一点。如果你期望一个整数作为特定数学运算的结果,并且你得到了一个非常接近的数字,你可以使用Math.Round(Double, MidpointRounding)
方法来执行正确的舍入并弥补小错误(并确保你选择了the MidpointRounding
strategy you expect)。
简单铸造结果的类型,如byte
或int
不做四舍五入 - 它只是切断小数部分(甚至1.99999f
将成为1
当你只是将它转换为这些类型)。
十进制浮点运算速度较慢且内存密集程度较高,但不会导致这些错误。要执行此操作,请使用文字decimal
而不是float
(例如64/0.8m
)。
decimal
。double
。float
。
我编辑了自己的冠军。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 – 2014-09-06 18:24:47
Jon Skeet的这篇文章应该涵盖你的问题:http://csharpindepth.com/articles/general/floatingpoint.aspx – Warlock 2014-09-06 19:02:20