我不知道为什么Ceiling的行为如下图所示
为什么是processingFee!= Settings.PaymentProcessingFeeInPercentage * prizesSum?
alt text http://img514.imageshack.us/img514/3950/csharpceilingproblem.png
答案 0 :(得分:25)
您的百分比实际上 0.05。这是 close 到0.05的值...并且可能略高于0.05。因此,当它乘以2600时,你得到一个超过130.0的值...然后被“天花板”到131.0。
使用我之前写过的一个小工具(可从this page获得关于.NET二进制浮点类型的信息),看起来最接近0.05的实际float
值是0.0500000007450580596923828125。对于双打,它是0.05000000000000000277555756156289135105907917022705078125。
故事的道德:不要将float
用于此类事情 - 请使用decimal
。或者,如果您只是想表示一个百分比,如果实际只能精确到百分之一,那么使用0-100的整数值。
答案 1 :(得分:4)
这是所涉及数字的浮点表示的结果。 See the wikipedia。可能0.05有一个无限的基数2表示为double,因此Math.Ceiling实际看到的值可能略大于130.
答案 2 :(得分:2)
你看到浮点不精确
0.05
的实际base-2表示比0.05
稍微多一点,因此产品比130.0
稍微多一点。
因此,Math.Ceiling
正在逐步推进。
将您的float
和double
更改为decimal
。
答案 3 :(得分:1)
这是由于当数字以十进制表示时,浮点数的内部存储格式固有地不精确。 Stack Overflow上有很多很多问题。
您返回的数字可能类似于130.000000000000001,因为计算中的数字不能完全表示为二进制浮点数。
答案 4 :(得分:1)
如果您尝试先将结果四舍五入,而不是致电Math.Ceiling
?
答案 5 :(得分:0)
在我的编译器中,当我查找乘法值时,它表示130.00000193715096,所以math.ceiling结果没问题。问题是浮点数据类型的精度有限。
如果可能,请尝试使用'double'。
答案 6 :(得分:0)
如果您在大型银行业务中使用浮点数,请不要让我将钱存入您的银行。使用小数或最小公分母的整数,即分数。
但是,如果您假设计算量有多大,则可以使用Math.Round
来帮助您使用double
或float
。即:
double processingFee = Math.Ceiling( Math.Round(
Settings.PaymentProcessingFeeInPercentage * prizesSum, 2 ) );