Special Simple Random Number Generator

Special simple random number generator

Linear congruential generators are one of the oldest and simplest methods:

int seed = 123456789;

int rand()
{
seed = (a * seed + c) % m;
return seed;
}

Only a few instruction with basic arithmetic operations, that's all you need.

Mind that this algorithm works fine only if a, c and m are chosen in a particular way!

To guarantee the longest possible period of this sequence, c and m should be coprime, a − 1 should be divisible by all prime factors of m, and also for 4 if m is divisible by 4.

Some examples of parameters are shown on Wikipedia: for example ANSI C for some compilers proposes m = 2 ³¹, a = 1103515245 and c = 12345.

How to generate a random int in C?

Note: Don't use rand() for security. If you need a cryptographically secure number, see this answer instead.

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

srand(time(NULL)); // Initialization, should only be called once.
int r = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.

On Linux, you might prefer to use random and srandom.

How do I generate random numbers without rand() function?

If you're after an ultra-simple pseudo-random generator, you can just use a Linear Feedback shift Register.

The wikipedia article has some code snippets for you to look at, but basically the code for a 16-bit generator will look something like this (lightly massaged from that page...)

  unsigned short lfsr = 0xACE1u;
unsigned bit;

unsigned rand()
{
bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
return lfsr = (lfsr >> 1) | (bit << 15);
}

generating simple random number with time in c

Static storage duration variables are initialised before any code starts running and they must be initialised with an expression calculable at compile time.

That means no using variables that can't be determined until run-time to initialise them. If you removed the static, the error would disappear but then you're going to re-seed the random number generator every time you call it.

You really should initialise the random seed once before asking for the first random number (as in srand()/rand() from the C standard library), and then use your random function to cycle through the values in the sequence. That could be done with something like:

int rand4 (int numLimit) {
static int randSeed, needsInit = 1;
if (needsInit) { // This bit only done once.
randSeed = time(0);
needsInit = 0;
}
randSeed = (randSeed * 32719 + 3) % 32749;
return (randSeed % numLimit) + 1;
}

A typical implementation of srand()/rand() is along the lines of:

// RAND_MAX assumed to be 32767.
static unsigned long int next = 1;
void srand(unsigned int seed) { next = seed; }
int rand(void) {
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}

in its own source file so that the next seed is hidden from view. This follows the expected behaviour that calling rand() without first calling srand() is the same as if you had called srand (1).


And, based on your comment that you need a certain number of calls to generate all the numbers from 1 to 52, it sounds like you're using this to generate a randomised deck of cards. If that's the case, there's a better way to do it than generating a random number and throwing away those you've already seen.

That solution deteriorates quickly as the size of the remaining deck gets smaller and smaller. For an O(1) time and space solution, use the Fisher-Yates shuffle.

The basic algorithm is to use an unsorted list and simply swap the final element with a randomly chosen one, reducing the list size by one:

dim n[N]                  // gives n[0] through n[N-1]

for each i in 0..N-1: // initialise them to their indexes
n[i] = i // (use i+1 for 1-10 instead of 0-9).

nsize = N // starting pool size
do N times:
i = rnd(nsize) // give a number between 0 and nsize-1
print n[i]
nsize = nsize - 1 // these two lines effectively remove the used number
n[i] = n[nsize]

The numbers generated by that are:

<------ n[] ------>
0 1 2 3 4 5 6 7 8 9 nsize rnd(nsize) output
------------------- ----- ---------- ------
0 1 2 3 4 5 6 7 8 9 10 4 4
0 1 2 3 9 5 6 7 8 9 7 7
0 1 2 3 9 5 6 8 8 2 2
0 1 8 3 9 5 6 7 6 6
0 1 8 3 9 5 6 0 0
5 1 8 3 9 5 2 8
5 1 9 3 4 1 1
5 3 9 3 0 5
9 3 2 1 3
9 1 0 9

Generating random whole numbers in JavaScript in a specific range

There are some examples on the Mozilla Developer Network page:

/**
* Returns a random number between min (inclusive) and max (exclusive)
*/
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}

/**
* Returns a random integer between min (inclusive) and max (inclusive).
* The value is no lower than min (or the next integer greater than min
* if min isn't an integer) and no greater than max (or the next integer
* lower than max if max isn't an integer).
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}

Here's the logic behind it. It's a simple rule of three:

Math.random() returns a Number between 0 (inclusive) and 1 (exclusive). So we have an interval like this:

[0 .................................... 1)

Now, we'd like a number between min (inclusive) and max (exclusive):

[0 .................................... 1)
[min .................................. max)

We can use the Math.random to get the correspondent in the [min, max) interval. But, first we should factor a little bit the problem by subtracting min from the second interval:

[0 .................................... 1)
[min - min ............................ max - min)

This gives:

[0 .................................... 1)
[0 .................................... max - min)

We may now apply Math.random and then calculate the correspondent. Let's choose a random number:

                Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)

So, in order to find x, we would do:

x = Math.random() * (max - min);

Don't forget to add min back, so that we get a number in the [min, max) interval:

x = Math.random() * (max - min) + min;

That was the first function from MDN. The second one, returns an integer between min and max, both inclusive.

Now for getting integers, you could use round, ceil or floor.

You could use Math.round(Math.random() * (max - min)) + min, this however gives a non-even distribution. Both, min and max only have approximately half the chance to roll:

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max

With max excluded from the interval, it has an even less chance to roll than min.

With Math.floor(Math.random() * (max - min +1)) + min you have a perfectly even distribution.

 min...  min+1...    ...      max-1... max....   (max+1 is excluded from interval)
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘ ← Math.floor()
min min+1 max-1 max

You can't use ceil() and -1 in that equation because max now had a slightly less chance to roll, but you can roll the (unwanted) min-1 result too.

Simple random number generator in Javascript

Here are several mistakes you made:

First of all, .getElementsByName() return array of DOM elements, not a single element you can get value from. So you should get value from first element in array using:

document.getElementsByName("startNumber")[0].value

or using another method like .querySelector(), which returns one element:

document.querySelector('input[name=startNumber]')

Also, you possibly save wrong elements state when you declare startNumber & endNumber variables on top-level / outside of event listener. Try to access to elements inside of listener:

form.addEventListener('submit', (e) => {
const startNumber = document.getElementsByName("startNumber")[0].value
...
})

Working snippet below, check this out:

const form = document.getElementById("randomForm");

form.addEventListener('submit', (e) => {
e.preventDefault();
const output = document.getElementById("output")
const startNumber = document.getElementsByName("startNumber")[0].value
const endNumber = document.getElementsByName("endNumber")[0].value
const rTal = Math.floor(Math.random() * (endNumber - startNumber) + startNumber)
output.innerText = rTal;
})
<div id="randomGenerator">
<div id="generatorText">
Do you want to calculate a random number?
<form id="randomForm">
<input type="number" name="startNumber" class="numbers">
<input type="number" name="endNumber" class="numbers">
<input type="submit" value="Generate">
</form>
<div id="finalNumber">Your random number is</div>
<div id="output"></div>

</div>
</div>

SIMPLE random number generation

As haskell is a pure functional programming language, functions are referentially transparent which means essentially that only a function's arguments determine its result. If you were able to pull a random number out of the air, you can imagine how that would cause problems.

I suppose you need something like this:

prefixGenerator :: (Ord a, Arbitrary a) => Gen ([a],[a])
prefixGenerator = do
randn <- choose (1,999) -- number in range 1-999
frequency [
(1, return ([],[])),
(2, do {
xs1 <- orderedListEj13 ;
xs2 <- orderedListEj13 ;
return (xs1,xs2)
}),
(2, do {
xs2 <- orderedListEj13 ;
return ((take randn xs2),xs2)
})
]

In general in haskell you approach random number generation by either pulling some randomness from the IO monad, or by maintaining a PRNG that is initialized with some integer seed hard-coded, or pulled from IO (gspr's comment is excellent).

Reading about how pseudo random number generators work might help you understand System.Random, and this might help as well (scroll down to section on randomness).

Generate 'n' unique random numbers within a range

If you just need sampling without replacement:

>>> import random
>>> random.sample(range(1, 100), 3)
[77, 52, 45]

random.sample takes a population and a sample size k and returns k random members of the population.

If you have to control for the case where k is larger than len(population), you need to be prepared to catch a ValueError:

>>> try:
... random.sample(range(1, 2), 3)
... except ValueError:
... print('Sample size exceeded population size.')
...
Sample size exceeded population size


Related Topics



Leave a reply



Submit