有没有一个函数生成一个随机int数在C?或者我必须使用第三方库?


当前回答

这是一个在你选择的两个数字之间得到一个随机数的好方法。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

    #define randnum(min, max) \
        ((rand() % (int)(((max) + 1) - (min))) + (min))

int main()
{
    srand(time(NULL));

    printf("%d\n", randnum(1, 70));
}

第一次输出:39

第二次输出:61

第三次输出:65

您可以将randnum后面的值更改为您选择的任何数字,它将在这两个数字之间为您生成一个随机数。

其他回答

你可以生成随机字符,然后将它们视为int:

#include <stdlib.h>
#include <stdio.h>

typedef double rand_type; // change double to int

rand_type my_rand() {
    char buff[sizeof(rand_type)];
    for (size_t i = 0 ; i < sizeof(rand_type) ; ++i)
        buff[i] = (char) rand();
    return *(rand_type *) buff;
}

int main() {
    int i ; // srand as you want
    for (i = 0 ; i < 10 ; ++i)
        printf("%g\n", my_rand()); // change %g to %d
    return 0 ;
}

如果您需要比stdlib提供的质量更好的伪随机数,请检查Mersenne Twister。它也更快。示例实现有很多,例如这里。

下面是我的方法(围绕rand()的包装器):

我还扩展到允许min为INT_MIN而max为INT_MAX的情况,这通常不可能单独使用rand(),因为它返回从0到RAND_MAX的值,包括(1/2范围)。

像这样使用它:

const int MIN = 1;
const int MAX = 1024;
// Get a pseudo-random number between MIN and MAX, **inclusive**.
// Seeding of the pseudo-random number generator automatically occurs
// the very first time you call it.
int random_num = utils_rand(MIN, MAX);

定义和氧描述:

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>

/// \brief      Use linear interpolation to rescale, or "map" value `val` from range
///             `in_min` to `in_max`, inclusive, to range `out_min` to `out_max`, inclusive.
/// \details    Similar to Arduino's ingenious `map()` function:
///             https://www.arduino.cc/reference/en/language/functions/math/map/
///
/// TODO(gabriel): turn this into a gcc statement expression instead to prevent the potential for
/// the "double evaluation" bug. See `MIN()` and `MAX()` above.
#define UTILS_MAP(val, in_min, in_max, out_min, out_max) \
    (((val) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min))

/// \brief      Obtain a pseudo-random integer value between `min` and `max`, **inclusive**.
/// \details    1. If `(max - min + 1) > RAND_MAX`, then the range of values returned will be
///             **scaled** to the range `max - min + 1`, and centered over the center of the
///             range at `(min + max)/2`. Scaling the numbers means that in the case of scaling,
///             not all numbers can even be reached. However, you will still be assured to have
///             a random distribution of numbers across the full range.
///             2. Also, the first time per program run that you call this function, it will
///             automatically seed the pseudo-random number generator with your system's
///             current time in seconds.
/// \param[in]  min         The minimum pseudo-random number you'd like, inclusive. Can be positive
///                         OR negative.
/// \param[in]  max         The maximum pseudo-random number you'd like, inclusive. Can be positive
///                         OR negative.
/// \return     A pseudo-random integer value between `min` and `max`, **inclusive**.
int utils_rand(int min, int max)
{
    static bool first_run = true;
    if (first_run)
    {
        // seed the pseudo-random number generator with the seconds time the very first run
        time_t time_now_sec = time(NULL);
        srand(time_now_sec);
        first_run = false;
    }

    int range = max - min + 1;
    int random_num = rand();  // random num from 0 to RAND_MAX, inclusive

    if (range > RAND_MAX)
    {
        static_assert(
            sizeof(long int) > sizeof(int),
            "This must be true or else the below mapping/scaling may have undefined overflow "
            "and not work properly. In such a case, try casting to `long long int` instead of "
            "just `long int`, and update this static_assert accordingly.");

        random_num = UTILS_MAP((long int)random_num, (long int)0, (long int)RAND_MAX, (long int)min,
                               (long int)max);
        return random_num;
    }

    // This is presumably a faster approach than the map/scaling function above, so do this faster
    // approach below whenever you don't **have** to do the more-complicated approach above.
    random_num %= range;
    random_num += min;

    return random_num;
}

参见:

[我在写下上面的答案后发现了这个问答,但它显然非常相关,他们对非缩放范围的情况做了同样的事情]我如何从rand()中获得特定的数字范围? [我需要进一步研究和阅读这个答案-似乎有一些好的观点,保持良好的随机性不使用模量]我如何从rand()得到一个特定的数字范围? http://c-faq.com/lib/randrange.html

您希望使用rand()。注意(非常重要):确保为rand函数设置了种子。如果你不这样做,你的随机数就不是真正的随机。这是非常、非常、非常重要的。值得庆幸的是,您通常可以使用系统滴答计时器和日期的某种组合来获得良好的种子。

FWIW,答案是肯定的,有一个stdlib.h函数叫rand;此函数主要针对速度和分布进行调优,而不是针对不可预测性。几乎所有语言和框架的内置随机函数都默认使用这个函数。还有“加密”随机数生成器,它们的可预测性要低得多,但运行速度要慢得多。在任何类型的与安全相关的应用程序中都应该使用它们。