C语言 生成范围内的随机数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2999075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:37:35  来源:igfitidea点击:

Generate a random number within range?

cobjective-cipad

提问by TheLearner

Possible Duplicate:
Generating Random Numbers in Objective-C

可能的重复:
在 Objective-C 中生成随机数

How do I generate a random number which is within a range?

如何生成一个范围内的随机数?

回答by Jerry Coffin

This is actually a bit harder to get really correct than most people realize:

这实际上比大多数人意识到的更难做到真正正确:

int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
 */

    int divisor = RAND_MAX/(limit+1);
    int retval;

    do { 
        retval = rand() / divisor;
    } while (retval > limit);

    return retval;
}

Attempts that just use %(or, equivalently, /) to get the numbers in a range almost inevitably introduce skew (i.e., some numbers will be generated more often than others).

尝试仅使用%(或等效地,/)获取某个范围内的数字几乎不可避免地会引入偏斜(即,某些数字将比其他数字更频繁地生成)。

As to why using %produces skewed results: unless the range you want is a divisor of RAND_MAX, skew is inevitable. If you start with small numbers, it's pretty easy to see why. Consider taking 10 pieces of candy (that we'll assume you can't cut, break, etc. into smaller pieces) and trying to divide it evenly between three children. Clearly it can't be done--if you hand out all the candy, the closest you can get is for two kids to get three pieces of candy, and one of them getting four.

至于为什么使用%会产生偏斜的结果:除非你想要的范围是RAND_MAX的除数,偏斜是不可避免的。如果您从小数字开始,很容易看出原因。考虑拿 10 块糖果(我们假设你不能把它们切成小块)并试着把它平均分给三个孩子。显然这是不可能的——如果你把所有的糖果都分发出去,你能得到的最接近的结果是两个孩子得到三块糖果,其中一个得到四块。

There's only one way for all the kids to get the same number of pieces of candy: make sure you don't hand out the last piece of candy at all.

只有一种方法可以让所有孩子得到相同数量的糖果:确保你根本不分发最后一块糖果。

To relate this to the code above, let's start by numbering the candies from 1 to 10 and the kids from 1 to 3. The initial division says since there are three kids, our divisor is three. We then pull a random candy from the bucket, look at its number and divide by three and hand it to that kid -- but if the result is greater than 3 (i.e. we've picked out candy number 10) we just don't hand it out at all -- we discard it and pick out another candy.

为了将其与上面的代码联系起来,让我们从 1 到 10 给糖果编号,从 1 到 3 给孩子编号。最初的除法表示,因为有三个孩子,我们的除数是 3。然后我们从桶中随机取出一颗糖果,查看它的数量并除以 3 并将其交给那个孩子——但如果结果大于 3(即我们选择了 10 号糖果),我们就不会把它分发出去——我们把它扔掉,然后再挑选一颗糖果。

Of course, if you're using a modern implementation of C++ (i.e., one that supports C++11 or newer), you should usually use one the distributionclasses from the standard library. The code above corresponds most closely with std::uniform_int_distribution, but the standard library also includes uniform_real_distributionas well as classes for a number of non-uniform distributions (Bernoulli, Poisson, normal, maybe a couple others I don't remember at the moment).

当然,如果您使用的是 C++ 的现代实现(即支持 C++11 或更新版本的实现),您通常应该使用distribution标准库中的类。上面的代码与 最接近std::uniform_int_distribution,但标准库还包括uniform_real_distribution许多非均匀分布的类(伯努利、泊松、正态,也许我现在不记得其他几个)。

回答by Micha? Trybus

int rand_range(int min_n, int max_n)
{
    return rand() % (max_n - min_n + 1) + min_n;
}

For fractions:

对于分数:

double rand_range(double min_n, double max_n)
{
    return (double)rand()/RAND_MAX * (max_n - min_n) + min_n;
}

回答by John Bode

For an integer value in the range [min,max):

对于 [min,max) 范围内的整数值:

double scale = (double) (max - min) / RAND_MAX;
int val = min + floor(rand() * scale) 

回答by Philip Regan

I wrote this specifically in Obj-C for an iPhone project:

我专门在 Obj-C 中为 iPhone 项目编写了以下内容:

- (int) intInRangeMinimum:(int)min andMaximum:(int)max {
    if (min > max) { return -1; }
    int adjustedMax = (max + 1) - min; // arc4random returns within the set {min, (max - 1)}
    int random = arc4random() % adjustedMax;
    int result = random + min;
    return result;
}

To use:

使用:

int newNumber = [aClass intInRangeMinimum:1 andMaximum:100]; 

Add salt to taste

加盐调味

回答by Tom H

+(NSInteger)randomNumberWithMin:(NSInteger)min WithMax:(NSInteger)max {
    if (min>max) {
        int tempMax=max;
        max=min;
        min=tempMax;
    }
    int randomy=arc4random() % (max-min+1);
    randomy=randomy+min;
    return randomy;
}

I use this method in a random number related class I made. Works well for my non-demanding needs, but may well be biased in some way.

我在我制作的随机数相关类中使用了这种方法。非常适合我的非苛刻需求,但很可能在某些方面存在偏见。