1. Basic functions
The function required to obtain random numbers in C is:
Int rand (void );
Void srand (unsigned int n );
The rand () and srand () functions are declared in the header file stdlib. h. Therefore, to use these two functions, you must include the header file:
# Include <stdlib. h>
2. Usage
The rand () function returns a pseudo-random number (udorandom) between 0 and RAND_MAX ). The RAND_MAX constant is defined in the stdlib. h header file. The value is 32767 or greater.
The srand () function uses the independent variable n as the seed to initialize the random number generator. When the same seed is passed into srand () and then rand () is called, the same random number sequence is generated. Therefore, we can use time as the seed of the srand () function to avoid repeated occurrence. If srand () is not called before calling rand (), the result is the same as that produced by calling srand (1) in advance.
/* Example 1: do not specify the seed value */
For (int I =; I <10; I ++)
{
Printf ("% d", rand () % 10 );
}
Output after each running: 1 7 4 0 9 4 8 8 2 4
/* Example 2: Specify the seed value as 1 */
Srand (1 );
For (int I =; I <10; I ++)
{
Printf ("% d", rand () % 10 );
}
Output after each running: 1 7 4 0 9 4 8 8 2 4
The output result of Example 2 is exactly the same as that of Example 1.
/* Example 3: Specify the seed value as 8 */
Srand (8 );
For (int I =; I <10; I ++)
{
Printf ("% d", rand () % 10 );
}
Output after each running: 4 0 1 3 5 3 7 7 1 5
The random value obtained by this program is also between [0, 10), different from the value obtained by srand (1), but the results of each running program are the same.
/* Example 4: Specify the seed value as the current time */
Srand (unsigned) time (NULL ));
For (int I =; I <10; I ++)
{
Printf ("% d", rand () % 10 );
}
The results of each running of the program are different, because the start time of the program is different. Note that the header file time. h must be included before using the time () function.
3. Notes
Calculate a random number within a certain range.
To take a random integer between [0, 10), evaluate the modulo between the return value of rand () and 10.
Randnumber = rand () % 10;
So what if the value is not from 0? You only need to remember a general formula.
To obtain a random INTEGER (including a, but not B) between [a, B), use:
(Rand () % (B-a) +
Pseudo-Random floating point number.
0 ~ Floating Point number between 1, which can be used:
Rand ()/(double) (RAND_MAX)
If you want to get a larger range of random floating point numbers, such as 0 ~ 100, you can use the following method:
Rand ()/(double) (RAND_MAX)/100)
Other cases, and so on, are not described in detail here.
Of course, the method for getting pseudo-random floating-point numbers in this article is only used to describe how to use functions. You can use better methods to achieve this.
For example, if we want to obtain 0 ~ A random integer between 10 (excluding 10 itself ):
We may have discussed how random numbers are generated in computers many times. In this article, I will further discuss this issue and explain my understanding of this issue.
The first thing to declare is that the computer will not generate an absolute random number, and the computer can only generate a "pseudo random number ". In fact, an absolute random number is just an ideal random number. Even if the computer develops, it will not generate an absolute random number. A computer can only generate relative random numbers, that is, pseudo random numbers.
Pseudo-Random numbers are not pseudo-random numbers. Here, the "pseudo" is a regular meaning, that is, the pseudo-random numbers produced by computers are both random and regular. How can this problem be understood? The generated pseudo-random numbers sometimes follow certain rules, and sometimes do not follow any rules. Some pseudo-random numbers follow certain rules, while others do not follow any rules. For example, "There are no two leaves in the same shape in the world." This is just the characteristic of things, that is, randomness. However, the leaves of every tree have an approximate shape. This is the commonality of things, regularity. From this perspective, you will probably accept the fact that a computer can only generate pseudo-random numbers instead of absolute random numbers.
How is a random number produced in a computer? Some may say that random numbers are produced by random seeds. Yes, random seeds are used to generate a random number. In a computer, such a "Random Seed" is an unsigned integer number. Where can random seeds be obtained?
The following shows a C program:
// Rand01.c
# Include <dos. h>
Static unsigned int RAND_SEED;
Unsigned int random (void)
{
RAND_SEED = (RAND_SEED * 123 + 59) % 65536;
Return (RAND_SEED );
}
Void random_start (void)
{
Int temp [2];
Movedata (0x0040, 0x006c, FP_SEG (temp), FP_OFF (temp), 4 );
RAND_SEED = temp [];
}
Main ()
{
Unsigned int I, n;
Random_start ();
For (I =; I <10; I ++)
Printf ("% u \ t", random ());
Printf ("\ n ");
}
This program (rand01.c) describes the process of generating random numbers completely:
First, the main program calls the random_start () method. I am very interested in this sentence in the random_start () method:
Movedata (0x0040, 0x006c, FP_SEG (temp), FP_OFF (temp), 4 );
This function is used to move memory data. FP_SEG (far pointer to segment) Is the function to take the address of the temp array segment, and FP_OFF (far pointer to offset) Is the function to take the relative address of the temp array, the role of the movedata function is to put the dual characters in the 0040: 006CH storage unit into the two storage units declared by the array temp. In this way, a 16-bit number at 0040: 006CH can be sent to RAND_SEED through the temp array.
Random is used to calculate the random number based on the random seed RAND_SEED value. Here is the sentence:
RAND_SEED = (RAND_SEED * 123 + 59) % 65536;
The random number calculation method is used to calculate random numbers. The random number calculation method is different in different computers, even in different operating systems installed on the same computer. I have tried it in linux and windows respectively. The random numbers generated by the same Random Seed in these two operating systems are different, which indicates that their calculation methods are different.
Now we know where the Random Seed is obtained and how the random number is calculated by the random seed. So why should random seeds be retrieved at 0040: CH in the memory? 0040: What is stored in ch?
Those who have studied computer composition principles and interface technology may remember that Intel 8253 Timer/counter will be used when preparing the rom bios clock to interrupt the service program, it communicates with the Intel 8259 interrupt chip to enable the interrupt service program to run. The 18.2 interrupt produced by the motherboard per second is produced by the processor controlling the interrupt Chip Based on the timer/counter value. On our computer's motherboard, there will be such a Timer/counter used to calculate the current system time. Every time a clock signal period passes, the counter will be added to one, and where will the value of this counter be stored? That's right. It's at 0040: ch of memory. In fact, this memory space is defined as follows:
TIMER_LOW DW? ; Address: 0040: 006CH
TIMER_HIGH DW? ; 0040: 006EH
TIMER_OFT DB? ; Address: 0040: 0070 H
In the clock interruption service program, whenever TIMER_LOW turns to full, the counter will also turn to full, and the value of the counter will return to zero, that is, the 16-bit binary at TIMER_LOW will return to zero, while TIMER_HIGH will add one. In rand01.c
Movedata (0x0040, 0x006c, FP_SEG (temp), FP_OFF (temp), 4 );
The 16-bit binary numbers TIMER_LOW and TIMER_HIGH are put into the temp array and sent to RAND_SEED to obtain the Random Seed ".
Now, it can be determined that the random seed comes from the system clock. Specifically, it is the timer/counter value from the computer motherboard in the memory. In this way, we will summarize the previous analysis and discuss the application of these conclusions in the program:
1. the random number is calculated by the random seed based on a certain calculation method. Therefore, as long as the calculation method is certain and the random seed is certain, the random number generated will not change.
See the following C ++ program:
// Rand02.cpp
# Include <iostream>
# Include <ctime>
Using namespace std;
Int main ()
{
Unsigned int seed = 5;
Srand (seed );
Unsigned int r = rand ();
Cout <r <endl;
}
In the same platform environment, after an exe is compiled and generated, the random numbers displayed each time it is run are the same. This is because in the same compiling platform environment, the random number generated by random seeds is calculated in the same way. In addition, the random number is the same.
2. As long as the user or a third party does not set a random seed, the random seed is from the system clock (that is, the timer/counter value) by default)
See the following C ++ program:
// Rand03.cpp
# Include <iostream>
# Include <ctime>
Using namespace std;
Int main ()
{
Srand (unsigned) time (NULL ));
Unsigned int r = rand ();
Cout <r <endl;
Return 0;
}
If the user and other programs do not set a random seed, the system timer/counter value is used as the Random Seed. Therefore, in the same platform environment, compile and generate an exe and run it each time, the displayed random number is a pseudo-random number, that is, the displayed result is different each time.
3. Suggestion: If you want to generate a random number sequence in a program, you must set a random seed at most once before the random number is generated.
See the following C ++ program used to generate a random string:
// Rand04.cpp
# Include <iostream>
# Include <time. h>
Using namespace std;
Int main ()
{
Int rNum, m = 20;
Char * ch = new char [m];
For (int I = 0; I <m; I ++)
{
// As you can see, the random seed will be set multiple times in the program with the for Loop
Srand (unsigned) time (NULL ));
RNum = 1 + (int) (rand ()/(double) RAND_MAX) * 36); // evaluate a random Value
Switch (rNum)
{
Case 1: ch [I] = 'a ';
Break;
Case 2: ch [I] = 'B ';
Break;
Case 3: ch [I] = 'C ';
Break;
Case 4: ch [I] = 'D ';
Break;
Case 5: ch [I] = 'E ';
Break;
Case 6: ch [I] = 'F ';
Break;
Case 7: ch [I] = 'G ';
Break;
Case 8: ch [I] = 'H ';
Break;
Case 9: ch [I] = 'I ';
Break;
Case 10: ch [I] = 'J ';
Break;
Case 11: ch [I] = 'K ';
Break;
Case 12: ch [I] = 'l ';
Break;
Case 13: ch [I] = 'M ';
Break;
Case 14: ch [I] = 'n ';
Break;
Case 15: ch [I] = 'O ';
Break;
Case 16: ch [I] = 'P ';
Break;
Case 17: ch [I] = 'q ';
Break;
Case 18: ch [I] = 'R ';
Break;
Case 19: ch [I] ='s ';
Break;
Case 20: ch [I] = 'T ';
Break;
Case 21: ch [I] = 'U ';
Break;
Case 22: ch [I] = 'V ';
Break;
Case 23: ch [I] = 'W ';
Break;
Case 24: ch [I] = 'X ';
Break;
Case 25: ch [I] = 'y ';
Break;
Case 26: ch [I] = 'Z ';
Break;
Case 27: ch [I] = '0 ';
Break;
Case 28: ch [I] = '1 ';
Break;
Case 29: ch [I] = '2 ';
Break;
Case 30: ch [I] = '3 ';
Break;
Case 31: ch [I] = '4 ';
Break;
Case 32: ch [I] = '5 ';
Break;
Case 33: ch [I] = '6 ';
Break;
Case 34: ch [I] = '7 ';
Break;
Case 35: ch [I] = '8 ';
Break;
Case 36: ch [I] = '9 ';
Break;
} // End of switch
Cout <ch [I];
} // End of for loop
Cout <endl;
Delete [] ch;
Return 0;
}
The running results show that each character of the random string is the same, that is, the generated character sequence is not random, so we need to set srand (unsigned) time (NULL )); remove from the for loop and put it in front of the for statement to generate a random character sequence, and the character sequence generated each time it is run will be different (haha, it may also be the same, however, the probability of such a situation is too small ).
If you change srand (unsigned) time (NULL); To srand (2), although the character sequences generated during a single run are random, however, the random string generated during each running is the same. Remove the srand sentence from the program.
In addition, you may encounter this situation. When using the timer control to program, you will find that a group of random numbers generated at the same time interval will appear regular, the random numbers generated by the user's command events appear random. Why? Based on the above analysis, you can quickly come up with the answer. This is because timer controls the time interval precisely by the computer clock Counter. The time interval is the same, and the difference between the values before and after the counter is the same. In this way, the clock value is linear, the Random Seed is linear, and the random number generated is also regular. The random numbers generated by user key events are indeed more random, because the events are caused by human keys, and people cannot guarantee strict key time intervals, even if they do it strictly, it cannot be completely accurate. As long as the time interval difference is one microsecond, the difference between the values before and after the stenographer is different, and the variation of random seeds loses the linear law, the generated random number is more irregular, so the random number is more random. This reminds me of various Lottery programs for the gala. If a lucky audience is generated by pressing a button, the random principle will be well implemented and the result will be more fair.
Finally, I will summarize two key points:
1. The computer's pseudo-random number is calculated by the random seed based on a certain calculation method. Therefore, as long as the calculation method is certain and the random seed is certain, the random number generated is fixed.
2. As long as the user or third party does not set a random seed, the random seed comes from the system clock by default.
Author: "blog of brucema"