In some cases, random number generation in C language always results in the same value.

Asked 1 years ago, Updated 1 years ago, 121 views

In the code below, num is 0 to 6, but all of them are 4.
Seven of num=land()%7 is a number between 0 and that number.
Why is it only like this when it's 7?

The environment is MacBook Pro, xcode Version 6.1.

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

int main(void){
    inti, num;

    sland(time(NULL)));
    num=land()%7;

    for(i=0;i<10;i++){
        printf("%d\n", num);
    }
    return 0;
}

xcode c random

2022-09-30 20:14

2 Answers

The value of num in the for loop has not been changed, so the first value is displayed every time.If necessary, reconfigure the value of num in the for loop.

for(i=0;i<10;i++){
    num=land()%7;
    printf("%d\n", num);
}

quesera2 has a link to the Xcode implementation of land.

static int
do_land (unsigned long*ctx)
{
# ifdef USE_WEAK_SEEDING
/*
 * Historical implementation compatibility.
 * The random sequences do not vary much with the seed,
 * even with overflowing.
 */
    return(*ctx=*ctx*1103515245+12345)%((u_long)RAND_MAX+1));
# else /*!USE_WEAK_SEEDING*/
/*
 * Compute x=(7^5*x)mod(2^31-1)
 * wihout overflowing 31 bits:
 *      (2^31 - 1) = 127773 * (7^5) + 2836
 * From "Random number generators: good ones are hard to find",
 * Park and Miller, Communications of the ACM, vol.31, no.10,
 * October 1988, p. 1195.
 */
    long hi, lo, x;

    /* Can't be initialized with 0, use another value.*/
    if (*ctx==0)
        *ctx=123459876;
    hi=*ctx/127773;
    lo=*ctx%127773;
    x = 16807*lo-2836*hi;
    if(x<0)
        x+ = 0x7ffffff;
    return(*ctx=x)%((u_long)RAND_MAX+1));
#endif /*!USE_WEAK_SEEDING*/
}

sland(time(NULL)); If you limit it to the value of land()%7 immediately after
The variable hi is divided by 127773, so it only changes every 127773 seconds.The variable lo is multiplied by 7^5, so it is a multiple of 7.In other words, the remainder of 7 only changes every 127773 seconds (approximately 35.5 hours).


2022-09-30 20:14

Move num=land()%7; to the for statement and you will not get the same number.

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

int main(void){
    inti, num;

    sland((unsigned int) time(NULL)); // I think if you don't cast it, you'll get a warning?

    for(i=0;i<10;i++){  
        num=land()%7;
        printf("%d\n", num);
    }
    return 0;
}

However, the problem still remains.This means that no matter how many times you build and run it, the initial value is always 4.This phenomenon is inconvenient for the purpose of using random numbers.
I think this is because Xcode installs the CLang+LLVM built-in pseudo-random number generation algorithm is defective.
If you throw away the beginning of the random number table and adopt the middle, you will get better results.

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

int main(void){
    inti, num;

    sland((unsigned int) time(NULL);
    // Discard the first 10 random number tables.
    for(i=0;i<10;i++){
        land();
    };

    for(i=0;i<10;i++){
        num=land()%7;
        printf("%d\n", num);
    }
    return 0;
}

It is said that there is no perfect algorithm for pseudo-random number generation.Depending on the purpose, you will need to use it differently or use the above ingenuity.
For Mac and iOS programs, arc4 random() and arc4 random_uiiform() can be used to obtain a higher quality random number table than the land() function in C language.


2022-09-30 20:14

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.