簡體   English   中英

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

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

操作如下:

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

價值觀是:

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

返回的值是-63

100改為100f解決這個問題。


為什么該操作返回-63而不是63

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 undecillion,即相當多),所以它是確實是正確的。

這是整數溢出錯誤

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可以防止出現這個問題,因為float不會長時間溢出,而且當它浮出時它最終會變為無限。

問題的解決方案是強制浮動乘法,就像使用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)

可能不是瓶頸,但如果它是一個實時游戲,你可能會獲得更好的性能,因為你避免將intfloat (當然,這可能是一個微優化,取決於你調用它的頻率)。

編輯 - 正如克里斯在評論中正確提到的那樣,在這種情況下最好使用long而不是uint

一個整數可以容納的最大數是2,147,483,647。 如果您感染的變量和僵屍都是整數,則它們會超過此數字,因為{(被感染的+僵屍)* 100} = 2,217,423,100> 2,147,483,647。 因為它最大化了整數,所以進入負數。 嘗試將感染和僵屍變量變為浮點數或通過將100變為100.00來強制浮點乘法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM