|
|
This thread is locked; no one can reply to it.
|
1
2
|
| RPG Combat |
|
spellcaster
Member #1,493
September 2001
|
I know It's not a real issue here. For your normal RPG issues, it's not a big problem. Hope you agree here -- |
|
Korval
Member #1,538
September 2001
|
Quote: For your normal RPG issues, it's not a big problem. So, let me get this right. Rather than taking a minimal amount of effort to correct the random function, you'd rather just do it the wrong way and live with the slightly skewed probability? It's not like you even have to think of a solution; it's right here in this thread! You're arguing against chaning one line of code from doing something that's slightly wrong to doing something that perfectly right. Um, OK, whatever you want to do. It's your code. |
|
spellcaster
Member #1,493
September 2001
|
Quote: Rather than taking a minimal amount of effort to correct the random function, you'd rather just do it the wrong way and live with the slightly skewed probability?
Nope. As I said, I had always around 0.1 percent fluctation. And that's good enough for me [EDIT] Quote:
Doing 4294967294 rolls... Doing 4294967294 rolls the Korval way...
In other words... there's no difference. Never assume. Always test -- |
|
Korval
Member #1,538
September 2001
|
Quote: Ok, I tried your function. It isn't my function or your function. There is simply the right way and the wrong way. Quote: Never assume. Always test Whatever. All your "tests" have shown is a lack of understanding of probability, statistics, and statistical variance. You aren't even doing the right tests (and you don't even use "srand" to seed the generator beforehand). The fact is that, given a roll between 0 and 99, using a RAND_MAX of 0x7FFF, using the %100 method, the chance of rolling a number greater than 67 is precisely 31.93% (32 numbers greater than 67 * 327/32767). However, that's not what it should be. The chance of rolling a number greater than 67 should be precisely 32%. You are off by a 0.07%. This is not something that came up through testing. This number is an absolute, incontrovertible fact. 0.07% may not seem like much, but it is significant. And I can even make it show up in your program, simply by doing the right test. Add up all counts <= 67. Add up all counts > 67. Divide both by MAX_TEST and * 100.0f to get percent. Given sufficient tests (0xFFFFFFF works and is faster than the full MAX_INT), you will never get the percentages you should. In fact, you will get precisely what the math says you should (ie, skewed probabilities). And if you switch to the right random method, you'll get the right probabilities. |
|
Bob
Free Market Evangelist
September 2000
|
Let's not resort to flames, shall we? -- |
|
dudaskank
Member #561
July 2000
|
dudaskank: FireBlast!!! hehehe Hmm... I will test the codes tomorrow... my idea too... I don't like much statistics :-P see you space cowboy ^__^ Toque a balada do amor inabalável, eterna love song de nós dois |
|
spellcaster
Member #1,493
September 2001
|
Quote: All your "tests" have shown is a lack of understanding of probability, statistics, and statistical variance. You aren't even doing the right tests (and you don't even use "srand" to seed the generator beforehand).
Hm... a random number generator returns random numbers... so I thought the best way to test it would be by using it to create random numbers? But I must admit that I'm surprised that your way works as good as the modulo way. In fact, I expected it to create worse numbers (due to the lack of precision if using floats). Hm... and given the fact that using floats (your method) generates the same distribution of numbers clearly shows that it doesn't make a big difference. I'm not sure you understand this: So, could you please tell me, if I get exectly the same results with either method, why is your method better? If you believe it should be better, then this shows that rand() itself is the main problem, not the if you use a modulo or multiplication... Quote: Add up all counts <= 67. Add up all counts > 67. Divide both by MAX_TEST and * 100.0f to get percent. Given sufficient tests (0xFFFFFFF works and is faster than the full MAX_INT), you will never get the percentages you should
What results should I get? I don't get your point. I don't get it. I even made a version which created buffers showing the distribution of the numbers... I still don't see a difference. Could you please provide me with an example? Oh, and just in case you want to have the latest version of the test proggy:
-- |
|
Korval
Member #1,538
September 2001
|
I thought I had made the problem appropriately clear in my original post on the subject. So, let me made an addendum to it. Original: Quote: Well, if you went and actually rolled 2D10 several million times (limit as number of rolls approaches infinity), you should hit each number the same number of times. In short, the probability of rolling a 4 is the same as rolling an 86 or a 34, or any other values from 0 to 99. Keeping that in mind, let's say RAND_MAX is 150. It probably isn't, but let's say it is for the sake of argument. What is the probability, using rand() % 100, of rolling a 66? The only way rand() % 100 == 66 is if rand() == 66. So, the probability (assuming a perfect rand()) is 1/150. What is the probability of rolling 8? Well, if rand() == 8, then rand()%100 == 8. But, if rand() == 108, then rand()%100 == 8 too. Therefore, the probability is 2/150. Your probabilities are now no longer correct. Given this example, it is twice as likely to come up with a number less than 50 than it is to come up with one greater than 50. The correct way to do this is to check to see if rand() >= (RAND_MAX - RAND_MAX % 100). If it is, then redo the rand() until it is. BTW, good coding practice says that this should be made its own function. This way, your probabilities will be correct, to the degree that rand() is probabilistically accurate. Taking the case where RAND_MAX is 32767, there are 327 ways of coming up with the number 99 from "rand()%100". That is ***99, where *** is any number less than 327, including 000. As such, the probability of comping up with 99 is 327/32767. Note that, because 99 is greater than 67, if *** is 327, rand() will never return 99. Now, the probability of getting 2 is different from 99. This is because, unlike the 99 case, *** can be 327. rand() could return 32702, and this would come up with 2 as a result. Therefore, the number of ways to get 2 from "rand()%100" is 328, not 327 as above. And, therefore, the probability is 328/32767. Given a probabilistically correct 0-99 roll, the probability of rolling a number less than or equal to n (0 <= n <= 99) is exactly (n+1)%. That is, the probability of rolling a number less than or equal to 67 should be exactly 68%. BTW, to make sure you follow along, you get this by taking the probability of rolling any number 0-99 (this should be 1/100, one chance in a hundred) and multiply it times the number of values you're checking. Since there are 68 numbers <= 67, you get 68 *1/100, or 68/100, or 68%. If you use your method to compute the probability (using the following code), then you will find that the chances of rolling a number <= 67 is actually 68.07%. This is because the probability of rolling a number <= 67 is actually 328/32767. This number is slightly more than 1/100. The probability of rolling <= 67 in your method is 68 * 328/32767 which equals 68.07%. Likewise, the probability of rolling avobe 67 is altered as well (obviously, since the probability of rolling <= or > 68 must be 100% Here's a version of your tester program that will verify this. Note that it computes the probability of rolling <= 67 and > 67. You will find, even under repeated testing, that your method and mine differ significantly. You can change them easily enough by uncommenting my method out.
As for your concerns about precision: don't be. As long as RAND_MAX is only 32767, floats will work just find. Granted, you might want to use doubles anyway, just to be safe (incase some implementation uses an int RAND_MAX rather than a short one). Granted, if RAND_MAX is that huge, the probability skew won't be very significant. As for your concerns about speed: don't be. After all, how many times are you planning on calling this function per frame? 20? 30? Compared to rendering, this is nothing. |
|
spellcaster
Member #1,493
September 2001
|
Ok, I understand that theory. 10.000 times I rolled 6600000 random numbers using both your method and mine. Result: Quote:
Per cent below 67 (spellcaster) : 67.087 But I don't see in which application this would become a problem? But I bet you're going to say that this distribution will cause a problem, right? Quote:
Per cent below 67 (spellcaster) : 67.006
Oups Hm.. guess we have a draw here. So, use your method for number genrators with a low RAND_MAX, and use the modulo as soon as you can use better RNGs... -- |
|
dudaskank
Member #561
July 2000
|
Here is the code:
And my results, using D20:
and other results, with spellcaster modulo:
See, the results is very dependent of the ammount of rolls, because the result of rand() depends of the last result. Toque a balada do amor inabalável, eterna love song de nós dois |
|
spellcaster
Member #1,493
September 2001
|
Dudaskank... if you need a good ditribution, use this random number generator: You could also check for other generators, ther're some generators available which are pretty good and really fast. -- |
|
|
1
2
|