# Why use this equation to get a percentage?

In an XNA book I read that this code does an action with a 0.2% of probability but I don't' understand why:

float chance = 0.2f;

if((float)rand.Next(0,1000) / 10 <= chance)
{
...
}

I understand the statement, but not the reasoning for that equation. Can anyone explain me, please?

-
Is your actual question: 'why do it like this' or is it 'how does this work'? If it's the first then I can only say: no idea why, else see all the answers :). – Roy T. Jul 23 '12 at 14:21

(float)rand.Next(0,1000) / 10

Picks a random number between 0 and 1000, the divides by 10. This gives you a random number between 0 and 100. If that random number is less than or equal to your chance (<= .2), then the statement is true and whatever is inside the if statement is executed.

If you want to get a .2% chance, that means that for every .2% of the times you run this code it will be true. So how do we do that? Pick a random number between 0 and 100, if it's less than .2 it's true.

Throw a random dart at this image:

If the dart were truly random, you'd expect it to hit blue 50% of the time and red 50% of the time. So we want something to happen 50% of the time, this is what we would use. So what if we wanted it to happen .2% of the time? I means our image needs to look at bit less equal.

Throw that random dart at this image and you'll hit blue .2% of the time.

As you can see, there are times where if you stopped right then, things would look very unbalanced. But as the sample size continues to grow, it does start to equalize towards 50/50. You can also see that I got lucky and this animated gif matches the color scheme I picked :).

Probability belongs to statistics. Statistics is one thing that people are typically not good at (if you need proof of that, just look at all the lottery players). It is however very beneficial to study statistics. It'll help you in programming and life in general.

Basically what you should take away from this is:

• Random numbers are not affected by any number that appeared before or after them.
• With small sample sizes, the distribution of probability might look wrong, so don't worry.
• The lottery is a tax for people who don't know statistics
• Random numbers do not guarantee their distribution
• Know statistics well and you will be a superhero
-
Yes, maybe I explain the question bad! I understand the statement, I don't understand why that equation! P.S. A number is taken between 0 and 999... – xdevel2000 Jul 23 '12 at 14:13
@xdevel2000: you should update the question accordingly to explain a little bit more what you expect form the answers. I tried to give a different explanation, if that was what you were looking for. – Jesse Emond Jul 23 '12 at 14:27
+1 for the awesome drawings ;) – Jesse Emond Jul 23 '12 at 23:54
Yes, good answer and thanks for the images :) However when you say that having 50f give us a 50% of probability if I run the code with this value I have some time that the number generated, some time, is not 50% lesser than 50 and 50% greater then 50. In fact I have, for example, 76 59,7 95,5 31,4 so 3 time greater than 50 and one time lesser. Why? – xdevel2000 Jul 24 '12 at 7:11
Down voter care to comment? – Byte56 Jul 24 '12 at 15:31

There is no reason. It's just a stupid thing which works but is completely unnecessary. The author probably just wanted to write down the chance as percent and not as permille .

Better is:

// In Permille: 2‰ == 0.2% == 0.002
int chance=2;
if(rand.Next(0, 1000) <= chance)
{
[...]
}

It will give you the same result but without those divisions and conversions to float.

Or if you prefer floating points over fixed numbers:

double chance=0.002;
if(rand.NextDouble() <= chance)
{
[...]
}
-
+1, seems the most likely explanation to me too. I'd be more inclined to go with the NextDouble alternative as there's less chance of someone coming along later and "correcting" it - all the others have some degree of ambiguity or lack of clarity as to what's going on, and good code shouldn't have that. – Le Comte du Merde-fou Jul 23 '12 at 17:38
As a native English speaker, "percent" is a very commonly used word, whereas "per mil" is extremely esoteric. – Jimmy Jul 23 '12 at 22:26

The part (float)rand.Next(0, 1000) generates a number between 0.0f and 999.0f inclusively.

Then, you divide it by 10 to get a number from 0.0f to 99.9f.

Checking if the number is below or equal to 0.2f checks if we hit the desired percentage, hence giving it a 0.2% chance of entering that if block.

Why the equation (float)rand.Next(0, 1000) / 10? Because you want to at least have a chance of getting into that if block.

If it had been simply rand.Next(0, 100), it would have entered the loop 1% of the time (when it would have given 0).

If my maths are not actually failing me this morning, by using the (float)rand.Next(0, 1000) / 10, you get the range from 0 to 2 (3 numbers) that give you a chance of entering that loop (since they are the only that x < 10 >= 0.2). 3/1000 gives your 0.003, or 0.3% chance (you'd have to remove that = from <= to get that actual 0.2%).

Instead, I recommend you to use rand.NextDouble() in your code. It is less obscure for other programmers (or yourself after a few months not looking at the piece of code) and more flexible.

Example of use in your context:

const float Chance = 0.2f; // I gave them programmers consts, programmers loooove const variables.
const float Percent = Chance / 100.0f; // divide by 100 to actually get the 0.2%

if (rand.NextDouble() < Percent)
{
...
}
-
Programmers seem to love unused const variables :) (Otherwise, good answer, +1) – bummzack Jul 23 '12 at 14:48
Interesting answer but, excuse me, why do you say that (float)rand.Next(0, 1000) / 10 get the range from 0 to 2 (3 numbers)? Maybe my maths is very rusty :) – xdevel2000 Jul 23 '12 at 15:40
0, 1, and 2 out of the random function that is going to give you from 0-999. After being divided by 10 those values will be 0.0f, 0.1f, and 0.2f all of which are less than or equal to 0.2f. If you limit it to just less than 0.2f, you'll get only 0.0f and 0.1f triggering (0 and 1 from the rand) which is 2/1000 (0.2%) of the possible results. – Lunin Jul 23 '12 at 17:46
@bummzack: silly me, I didn't even notice, even after writing the comment. – Jesse Emond Jul 24 '12 at 5:05

Sorry I misinterpreted your question, here is the actually working code simplified as much as possible so that it's easier to see what's going on.

double chance = 0.2; //we use real percentages now

//We choose a random number in [0...999] because we want enough precision for 1000
//different chances (100% to 0.1% or even 0%), we multiply our chance by 10 to
//move it from the 0.0~100 range into the 0~1000 range
if(Random.Next(0,1000) < chance * 10)
{
...
}

This is the old, wrong answer, here for reference only, I missed that it was .2% and not the 2% I assumed

I don't get the equation either its convoluted, we could do without the weird division by and 10 and it's not clear why a random number in [0...999] is chosen instead of a random number in [0..99], maybe that's why you're having trouble with it. Let's get rid of the unnecessary cast and the division and clean it up as much as we can. The equivalent and, in my opinion, much more readable version would be:

double chance = 2; //we use real percentages now
if(Random.Next(0, 100) < chance)
{
...
}
-
Perhaps the random number generator they were using was producing ints. – Byte56 Jul 23 '12 at 14:27
+1, clean alternative. – Jesse Emond Jul 23 '12 at 14:30
.2 out of 100 is .2%, not 2%. So the real percentage is still .2f. – Byte56 Jul 23 '12 at 14:34
Byte56, argh -1 for me, you're spot on, they were looking for .2% not 2%, I missed that dreaded point. – Roy T. Jul 23 '12 at 14:37
Na, it's a good answer. +1 – Byte56 Jul 23 '12 at 14:55