我不知道为什么天花板的行为如下图所示
为什么 processingFee != Settings.PaymentProcessingFeeInPercentage * PrizesSum ?
替代文字 http://img514.imageshack.us/img514/3950/csharpceilingproblem.png
我不知道为什么天花板的行为如下图所示
为什么 processingFee != Settings.PaymentProcessingFeeInPercentage * PrizesSum ?
替代文字 http://img514.imageshack.us/img514/3950/csharpceilingproblem.png
Your percentage isn't actually 0.05. It's a value close to 0.05... and probably a little bit more than 0.05. Thus when it's multiplied by 2600, you're getting a value just over 130.0... which is then being "ceilinged" to 131.0.
Using a little tool I wrote a while ago (available from this page about .NET binary floating point types) it looks like the actual float
value closest to 0.05 is 0.0500000007450580596923828125. For doubles, it's 0.05000000000000000277555756156289135105907917022705078125.
Moral of the story: don't use float
for this sort of thing - use decimal
. Or if you're just trying to represent a percentage, if it's okay to actually be only accurate to one percent, use an integer value 0-100.
这是所涉及数字的浮点表示的结果。请参阅维基百科。可能 0.05 具有无限基数 2 表示为双精度,因此 Math.Ceiling 实际看到的值可能略大于 130。
您会看到浮点不精确。
的实际 base-2 表示0.05
略多于0.05
,因此乘积略多于130.0
。
因此,Math.Ceiling
正在四舍五入。
float
将您的 s 和double
s更改为decimal
。
这是因为当数字以十进制表示时,浮点数的内部存储格式本质上是不精确的。Stack Overflow 上有很多很多关于此的问题。
您返回的数字可能类似于 130.000000000000001,因为您计算中的数字不能完全表示为二进制浮点数。
恕我直言,这可能与浮点精度有关。换句话说,2600 × 0.05 给出 130.0000...001 而不是 130。
如果您尝试先对结果进行四舍五入,而不是 callMath.Ceiling
怎么办?
In my compiler, when i lookup the multiply value, it says 130.00000193715096, so the math.ceiling result is ok. The problem is the limited precision of the float data type.
Try using 'double' instead, if it is possible.
If you use floating point numbers in a large banking operation, don't let me float my money in your bank. Use decimals, or integers of the least common denominator, i.e. cents.
You could however, use a Math.Round
, to help you use double
s or float
s, if you make assumptions about how large your calculations will get. i.e.:
double processingFee = Math.Ceiling( Math.Round(
Settings.PaymentProcessingFeeInPercentage * prizesSum, 2 ) );