简体   繁体   English

C# - Int操作莫名其妙地返回负值

[英]C# - Int operation inexplicably returning negative value

Operation is as follows: 操作如下:

public float InfectionPercent()
{
    return (infected + zombies) * 100 / population;
}

the values are: 价值观是:

int infected = 20196093
int zombies = 1978138
int population = 32608521

The value returned is -63 返回的值是-63

Changing 100 to 100f fixes this. 100改为100f解决这个问题。


Why is that operation returning -63 instead of 63 ? 为什么该操作返回-63而不是63

20196093 + 1978138 = 22174231
22174231 * 100 = 2 217 423 100

However, Int.MaxValue is 2 147 483 647 , so you're busting the max value. 但是,Int.MaxValue是2 147 483 647 ,所以你破坏了最大值。

By setting 100 as a float you are forcing a float multiplication. 通过将100设置为float您将强制浮点乘法。 Valid float values are be between -3.4 × 10^38 and +3.4 × 10^38 (which is 340 undecillion, ie quite a lot) so it is indeed correct. 有效float值介于-3.4 × 10^38+3.4 × 10^38 (它是340 undecillion,即相当多),所以它是确实是正确的。

This is an integer overflow error 这是整数溢出错误

2,147,483,647 is the max c# integer value 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

(integer overflows to -2,077,544,195 ) (整数溢出到-2,077,544,195

-2,077,544,195 / 32,608,521 = -63.71169655318007

Converting to float prevents this issue because float does not overflow for a long time and when it does it ends up being infinite. 转换为float可以防止出现这个问题,因为float不会长时间溢出,而且当它浮出时它最终会变为无限。

A solution to the problem would be to forcing a float multiplication like you did by using 100f (for reasons explained by Pierre-Luc Pineault). 问题的解决方案是强制浮动乘法,就像使用100f (由Pierre-Luc Pineault解释的原因)。 However, if you want a whole number result returned without casting explicitly, make your variables uint as they can only be positive. 但是,如果您希望在没有明确强制转换的情况下返回整数结果,请将变量设为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)

Might not be a bottleneck but if it's a realtime game, you'll likely get better performance because you're avoiding the casting of int to float (of course, that might be a micro-optimization depending on how often you call it). 可能不是瓶颈,但如果它是一个实时游戏,你可能会获得更好的性能,因为你避免将intfloat (当然,这可能是一个微优化,取决于你调用它的频率)。

Edit - As Chris correctly mentioned in the comments, it'd better to use long instead of uint in this case. 编辑 - 正如克里斯在评论中正确提到的那样,在这种情况下最好使用long而不是uint

max number an integer can hold is 2,147,483,647. 一个整数可以容纳的最大数是2,147,483,647。 If your variables infected and zombies are both integers, they exceed this number because {(infected + zombies) * 100} = 2,217,423,100 > 2,147,483,647. 如果您感染的变量和僵尸都是整数,则它们会超过此数字,因为{(被感染的+僵尸)* 100} = 2,217,423,100> 2,147,483,647。 Because it maxes out the integer number, is goes into negatives. 因为它最大化了整数,所以进入负数。 Try to make the infected and zombies variables into floats or force a float multiplication by making 100 into 100.00. 尝试将感染和僵尸变量变为浮点数或通过将100变为100.00来强制浮点乘法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM