RadiantHex
RadiantHex

Reputation: 25557

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

Changing 100 to 100f fixes this.


Why is that operation returning -63 instead of 63?

Upvotes: 3

Views: 1432

Answers (4)

Logan Murphy
Logan Murphy

Reputation: 6230

This is an integer overflow error

2,147,483,647 is the max c# integer value

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 / 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.

Upvotes: 3

keyboardP
keyboardP

Reputation: 69372

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). However, if you want a whole number result returned without casting explicitly, make your variables uint as they can only be positive.

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).

Edit - As Chris correctly mentioned in the comments, it'd better to use long instead of uint in this case.

Upvotes: 1

Pierre-Luc Pineault
Pierre-Luc Pineault

Reputation: 9191

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

However, Int.MaxValue is 2 147 483 647, so you're busting the max value.

By setting 100 as a float you are forcing a float multiplication. Valid float values are be between -3.4 × 10^38 and +3.4 × 10^38 (which is 340 undecillion, i.e. quite a lot) so it is indeed correct.

Upvotes: 8

mundo
mundo

Reputation: 1

max number an integer can hold is 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. 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.

Upvotes: 0

Related Questions