操作如下:
public float InfectionPercent()
{
return (infected + zombies) * 100 / population;
}
值为:
int infected = 20196093
int zombies = 1978138
int population = 32608521
返回的值为-63
将100
更改为100f
可解决此问题。
为什么该操作返回-63
而不是63
?
答案 0 :(得分:8)
20196093 + 1978138 = 22174231
22174231 * 100 = 2 217 423 100
但是,Int.MaxValue为2 147 483 647
,因此您破坏了最大值。
通过将100
设置为float
,您正在强制浮点乘法。有效的float
值介于-3.4 × 10^38
和+3.4 × 10^38
之间(这是340十亿分之一,即非常多),所以它确实是正确的。
答案 1 :(得分:3)
这是一个整数溢出错误
2,147,483,647
是最大c#整数值
20,196,093 + 1,978,138 = 22,174,231
22,174,231 * 100 = 22,174,231 * 100 = 2,217,423,100
(整数溢出到-2,077,544,195
)
-2,077,544,195 / 32,608,521 = -63.71169655318007
转换为float可以防止出现这个问题,因为浮动不会长时间溢出,而且一旦浮动就会无限期地溢出。
答案 2 :(得分:1)
问题的解决方案是强制浮动乘法,就像使用100f
一样(由Pierre-Luc Pineault解释的原因)。但是,如果您希望在未明确强制转换的情况下返回整数结果,请创建变量uint
,因为它们只能是正数。
uint infected = 20196093
uint zombies = 1978138
uint population = 32608521
public uint InfectionPercent()
{
return (infected + zombies) * 100 / population;
}
//output is 68 (float output is 68.00134)
可能不是瓶颈,但如果它是实时游戏,你可能会获得更好的表现,因为你避免将int
投射到float
(当然,这可能是微观的 - 优化取决于你调用它的频率。)
修改 - 正如Chris在评论中正确提到的那样,在这种情况下最好使用long
代替uint
。
答案 3 :(得分:0)
一个整数可以容纳的最大数是2,147,483,647。如果你的变量被感染并且僵尸都是整数,那么它们会超过这个数字,因为{(被感染的+僵尸)* 100} = 2,217,423,100> 2,147,483,647。因为它最大化了整数,所以进入负数。尝试将感染和僵尸变量变为浮点数或通过将100变为100.00来强制浮点乘法。