Are there any other ways to get a random number in a certain range? rand() for the existing task is not suitable at all. For example, I wrote a console game where the hero has a critical strike chance. On my computer almost every 3rd hit is critical (with chances of 26%), and on a computer from a friend with the same chances it is not a fact that there will be a critical hit at all.

srand(time(0)); it is registered.

I do this:

 if (rand()%100 > critical_chance) {...} 
  • If you have a chance of 26, and if (rand()%100 > critical_chance) {...} written, then the condition will be satisfied in 73/100. Change the> sign to <=. - h86C1p
  • There is a mistake in the sign in question. Mixed up) "<" is worth - Vlad
  • Well, 26 out of 100 - this is almost every third. More precisely, every fourth. I do not understand what the problem is. And who has "him"? - Qwertiy
  • Have a friend. I apologize - Vlad

3 answers 3

In C ++, there are different random number generators with different distributions. But in this case, it does not matter, because for such a simple goal rand() is quite adequate, although, of course, its range is not so great. And yet - srand(time(0)); - it's just adding randomness, nothing more, but not affecting the properties of the generator.

Simplest test

 int chances(int value) { int count = 0; for(int i = 0; i < 1000; ++i) { if (rand()%100 < value) ++count; } return count; } int main(int argc, const char * argv[]) { srand(time(0)); for(int value = 0; value < 100; value += 10) { int count = chances(value); printf("%3d : %3d.%01d\n",value, count/10,count%10); } } 

Gives a result on Visual C ++ 2015 (it is clear that with fluctuations from launch to launch)

  0 : 0.0 10 : 11.3 20 : 22.1 30 : 29.7 40 : 40.7 50 : 51.5 60 : 59.2 70 : 70.6 80 : 79.0 90 : 89.9 

Here you can see the result for GCC.

You can - if you want - use the option

 std::default_random_engine u{}; std::uniform_int_distribution<> d{}; u.seed(std::random_device()()); // Аналог srand d(u,uniform_int_distribution<>::param_type{0,100}); // - аналог rand()%100 

It is even more correct to use in this case

 bernoulli_distribution b; // Замена вашего if (rand()%100 < critical_chance) if (b(u,std::bernoulli_distribution::param_type{critical_chance/100.0})) { ... }; 
  • rand cannot be adequate, even for such a simple task, since it is not known what kind of distribution it gives and, because of its limitations, it biased. - ixSci
  • one
    @ixSci Generator uniformity is checked in any case. He may not pass tests for any autocorrelation, but for the simplest choice of chances he will just work out. So that there is not one time at the threshold of 26% - roughly speaking, there will not be such (un) happiness. Yes, for three attempts - I will believe, but any generator, even a quantum one, can give :) Show an example of at least one modern compiler where the RNG will not pass chi-square for uniformity ... - Harry
  • Which one? Who told you that rand () produces a uniform distribution? Where is that written? - ixSci
  • one
    I do not understand what is the difficulty in writing in answers in normal C ++? In both standards (C and C ++), rand() is declared obsolete in various words, and people persist in writing it in their answers. I will put the cons for rand() in the answers. - ixSci
  • @ixSci As the saying goes, do you have to checkers or do you have to go? Let me be wrong, but personally I have to write 5 lines of long code with unpredictable names instead of simple rand () - which could have been built on the basis of more modern generators for a long time - causes no less rejection than the <chrono> library with its frantic verbosity .. By the way, not only for me - for some members of the committee too :) - Harry

The <random> header file for C ++ 11 includes the generation of PNS for different distribution curves: uniform, Bernuli, normal. If without C ++ 11 support, then this module is included in the boost library.

    Because probabilities need to be multiplied, given the failures on previous moves

     double getProb(double AProb, int AIdx) { return 1 - (1 - AProb) * (AIdx + 1); } for (int i = 0; life > 0; i++) { if rand() < getProb(critical_chance, i) { .......... } } 
    • Why is it necessary? - Qwertiy
    • four
      Events are independent, do not need to multiply anything. - ixSci