Thread: My random number generator. (Looking for feedback)

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    121

    My random number generator. (Looking for feedback)

    I have come up with a random number generator. Can someone tell me if this is good or bad and why?

    I basically take the nanoseconds from system time and modulus it with the users max value. Adjusting for starting point.

    Code:
    #include <stdio.h>
    #include <libgen.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <time.h>
    
    // Declare defines.
    #define PROGRAM_NAME_SIZE   50
    
    // Declare function prototypes.
    long random_number (long max, int start);
    
    // Declare global variables.
    char program_name[PROGRAM_NAME_SIZE + 1] = {0};
    
    int main (int argc, char *argv[])
    {
    // Get program name for error reporting.
        strcpy(program_name, basename(argv[0]));
    
    // Check for correct number of arguments.
        if(argc != 3)
        {
            fprintf(stderr, "usage: %s MAX_VALUE START\n", program_name);
            fprintf(stderr, "%s: START is either 0 or 1\n", program_name);
            exit(EXIT_FAILURE);
        }
    
    // Get random numbers forever.
        while(1)
            printf("%ld\n", random_number(atol(argv[1]), atoi(argv[2])));
    
    // Exit gracefully.
        exit(EXIT_SUCCESS);
    }
    
    long random_number (long max, int start)
    {
    // Declare variables.
        long number = {0};
        struct timespec tp = {0};
    
    // Get the current time.
        if(clock_gettime(CLOCK_REALTIME, &tp) == 1)
        {
            fprintf(stderr, "%s: random_number error: failed (%s)\n", program_name, strerror(errno));
            exit(EXIT_FAILURE);
        }
    
    // Calculate the random number.
        number = tp.tv_nsec % max;
    
    // Change number depending on start.
        if(start == 1)
            if(number == 0)
                number = max;
    
    // Return the number.
        return(number);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > Can someone tell me if this is good or bad and why?
    It's awful, truly awful.

    Seriously, don't even suggest this is a random number generator.

    It isn't.

    Code:
        int histogram[100] = { 0 };
        for ( int i = 0 ; i < 1000000 ; i++ ) {
            long n = random_number(100,0);
            histogram[n]++;
        }
        for ( int i = 0 ; i < 100 ; i++ ) {
            printf("%d %d\n", i, histogram[i]);
        }
    Results in
    Code:
    0 12257
    1 13180
    2 12974
    3 13421
    4 13210
    5 13006
    6 12855
    7 13277
    8 12707
    9 13278
    10 13172
    11 12944
    12 13485
    13 13222
    14 13384
    15 13654
    16 11812
    17 10111
    18 8584
    19 8483
    20 8399
    21 8244
    22 8176
    23 8000
    24 8455
    25 8283
    26 8189
    27 8188
    28 8358
    29 8333
    30 8719
    31 8446
    32 8080
    33 8024
    34 8057
    35 8170
    36 8447
    37 8391
    38 8503
    39 8940
    40 8613
    41 8550
    42 8236
    43 7701
    44 8178
    45 8322
    46 8017
    47 8899
    48 8273
    49 8604
    50 11113
    51 11925
    52 12852
    53 12599
    54 12452
    55 12865
    56 12860
    57 13243
    58 13217
    59 12758
    60 13183
    61 13182
    62 12588
    63 13128
    64 12784
    65 12378
    66 13434
    67 12768
    68 10031
    69 8406
    70 8237
    71 8609
    72 8294
    73 8800
    74 8872
    75 8799
    76 8817
    77 8408
    78 8146
    79 8396
    80 8097
    81 8070
    82 8715
    83 8274
    84 8555
    85 8544
    86 8507
    87 8644
    88 8436
    89 7867
    90 8275
    91 7902
    92 8271
    93 8884
    94 8214
    95 8286
    96 8045
    97 7764
    98 8353
    99 10342
    Picking a modulus which is congruent to the cycle time of the loop will result in some values being returned far more often than would otherwise be expected.
    In the worst case, you end up with a stepped counter.
    Code:
        for ( int i = 0 ; i < 100 ; i++ ) {
            printf("%d %ld\n", i, random_number(1000000,0));
        }
    
    0 333106
    1 335437
    2 337008
    3 338460
    4 339900
    5 341341
    6 342776
    7 344219
    8 345655
    9 347091
    10 348527
    11 350011
    12 351456
    13 352878
    14 354304
    15 355735
    16 357165
    17 358595
    18 360030
    19 361457
    20 362885
    21 364317
    22 365749
    23 367186
    24 368617
    25 370041
    26 371467
    27 372900
    28 374324
    29 375752
    30 377176
    31 378602
    32 380025
    33 381456
    34 382887
    35 384313
    36 385739
    37 387166
    38 388590
    39 390019
    40 391447
    you can guess how this keeps going up slowly....
    90 510122
    91 511548
    92 512970
    93 514396
    94 515821
    95 517640
    96 523882
    97 525437
    98 526891
    99 528325
    Quote Originally Posted by manpage
    CLOCK_REALTIME
    System-wide clock that measures real (i.e., wall-clock) time. Setting this clock requires appropriate privileges. This clock is affected by discontinuous jumps in the system time
    (e.g., if the system administrator manually changes the clock), and by the incremental adjustments performed by adjtime(3) and NTP.
    External agents can mess about with the clock, making your so-called random numbers even worse.

    You're assuming that tv_nsec is actually as fast as it might suggest.
    You need to call clock_getres() to test that assumption.

    Famous Quote:
    Randomness is too important to be left to chance.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    62
    Code:
    // Calculate the random number.
        number = tp.tv_nsec % max;
    No. Very no. You should look up PRNG algorithms before trying to implement this. The LCG and XOR Shifter algorithms are very easy to implement and vastly superior to just getting the current time and dividing it.

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    121
    Quote Originally Posted by Salem View Post
    Famous Quote:
    Randomness is too important to be left to chance.
    Ty for showing me that I wasn't testing with a large enough data set. You really showed the lack of randomness. This explains why I have not seen this method used.


    Quote Originally Posted by gaxio View Post
    No. Very no. You should look up PRNG algorithms before trying to implement this. The LCG and XOR Shifter algorithms are very easy to implement and vastly superior to just getting the current time and dividing it.
    Ty for giving me a direction in which to learn more. This is why I wanted to post my code.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Feedback on prime number generator source code?
    By sepp in forum C Programming
    Replies: 5
    Last Post: 12-21-2014, 09:20 PM
  2. Random Number Generator Stuck on 1 Number?
    By Dollydaydream in forum C++ Programming
    Replies: 3
    Last Post: 11-26-2013, 08:43 AM
  3. Only getting 0; random number generator
    By scatterbrain in forum C Programming
    Replies: 10
    Last Post: 10-11-2011, 06:24 AM
  4. need a random number generator thats not compleatly random
    By thedodgeruk in forum C++ Programming
    Replies: 1
    Last Post: 06-05-2011, 06:48 AM
  5. random number generator
    By begginer in forum C Programming
    Replies: 5
    Last Post: 03-08-2011, 12:12 AM

Tags for this Thread