Jump to content

help making random number generator in C

Agent181

So I'm trying to do a 10 digit random number in c and I'm using codeblocks.

 

How would I get this done?

 

 

 

btw trying to learn C in 2 days and this is the only thing that I got stuck on, learned everything else and get it :D

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

Use rand() from stdlib.h. Unless you want to roll your own PRNG, at which point good luck.

Link to comment
Share on other sites

Link to post
Share on other sites

Use rand() from stdlib.h. Unless you want to roll your own PRNG, at which point good luck.

I used that to make random numbers but not sure how to make the number how to be exactly 10 digits every time 

Link to comment
Share on other sites

Link to post
Share on other sites

#define MASK 0x2540BE3FFrand() & MASK;

Wait so is it just using that and go straight  to a printf.... still trying to get this down

Link to comment
Share on other sites

Link to post
Share on other sites

 

@Agent181, you can use mod operator to limit the value. Try something like

rand() % 9999999999

EDIT: That suggestion was pretty stupid, don't do that. Use a Binary mask

#define MASK 0x2540BE3FFrand() & MASK;

Using mod was the right way to go.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

snip

 

 

 

I only get 5 random numbers from that

Link to comment
Share on other sites

Link to post
Share on other sites

Using mod was the right way to go.

Can you explain how to use it please?

Link to comment
Share on other sites

Link to post
Share on other sites

Can you explain how to use it please?

First you should check if rand() can even return a number that big. 

 

Try running this and see what is prints out

#include <stdio.h>#include <stdlib.h>int main(){	printf("%d\r\n",RAND_MAX);}

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

 

snip

only gets a 5 digit number max

Link to comment
Share on other sites

Link to post
Share on other sites

You can save computations with the binary mask, that's why I've suggested it =]

But it won't give the correct results. 

Plus as he said his rand() has a max of 5 digits (as does mine) so that also wouldn't generate big enough numbers.

 

only gets a 5 digit number max

 

In that case, I would say the easiest thing to do is create a string 10 characters long and generate the digits 1 at a time then convert it back to a number.

#include <stdio.h>#include <stdlib.h>int main(){	srand(time(NULL));        	char number[11];	number[10] = '\0';	int i;	for(i=0;i<10;++i)	{		int randomNumber = rand() % 10;		number[i] = randomNumber + '0';	}	long long newNumber = atoll(number);	printf("%lld",newNumber);}

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

What compiler, architecture and OS are you using? That's something really wrong with those 5 digit randomic numbers.

gcc on 64bit Windows 7

Using the mask will just cut the high order bits, that can change the distribution of the randomic numbers, but if you keep updating the seed, that doesn't make any difference.

It doesn't just change the distribution, it makes it impossible to generate a giant chunk of numbers.

9999999999 in binary is 0b1001010100000010111110001111111111

Your method makes it impossible to get any number that contains a 1 where that number has a 0, such as anything in the range 2147483648 - 8589934591 (more than half of the numbers.)

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

 

 

 

windows 8.1 64 bit

Link to comment
Share on other sites

Link to post
Share on other sites

Hmm, I've said a ton of shit, you're right. Was thinking in in something like 0x3FFFFFFFF and copied the wrong mask for the job. xD

 

But the 5 digit random is pretty bugged, I'm using gcc 4.8.3 x64 Windows 10 and got the right result.

a 5 digits RAND_MAX is ok according to the standard

http://www.cplusplus.com/reference/cstdlib/RAND_MAX/

 

on my platform RAND_MAX = INT_MAX = 2^31-1, which is still not enough because it's 10 digits long (2 billions and something) so it would never generate numbers over that limit (which are 80% of the space we're interested in)

Link to comment
Share on other sites

Link to post
Share on other sites

Could you just randomize each digit individually and use them to create your number?

 

If it always needs to be a 10 digit number, randomize 10 digits and build the number.

If it can be any number of digits from 1 to 10, then you could first randomize the number of digits the number will have and then randomize each digit.

You could then randomize if it's positive or negative if that's also a requirement.

 

This isn't as efficient, but that might not matter to you and should allow you to get around the RAND_MAX limit.

Link to comment
Share on other sites

Link to post
Share on other sites

It is not going to be pretty, but we should be able to keep 15 bits of every 16 bit rand int your library generates. That way, we should achieve a 60 bit random number, big enough to allow us to perform the modulus 9999999999 and still don't face distribution issues.

 

My C++ is a bit rusty, but based on gabriel's code:

 

 

#include <stdio.h>#include <stdlib.h>#include <time.h>#define LLRAND ((long long int)rand())int main(){	long long unsigned int random_int;	srand(time(NULL));	random_int = (LLRAND << 45 | LLRAND << 30 | LLRAND << 15 | LLRAND);	random_int = random_int % 9999999999;	printf("%llu\n", random_int);	return 0;}

 

That should generate a random int between 0 and 0xFFFFFFFFFFFFFFF before the modulus

Link to comment
Share on other sites

Link to post
Share on other sites

BTW, if you use this solution, you should either check the value of RAND_MAX on compile time to ensure is still 16bits. If you compile that code against a lib with 32bit rand, it will affect the randomness

 

So, you either check max value o force it to 0x7FFF:

#define LLRAND ((long long int)rand()&0x7FFF) // This is a horrible hack, but it will make it work for 16 and 32 implementations. Checking the RAND_MAX value on compile time will generate more eficient code

Link to comment
Share on other sites

Link to post
Share on other sites

Don't use rand(), it's terrible. It's not uniform and is terrible when you are trying to generate bigger numbers. You can copy paste a PRNG, like the Mersenne Twister, from the internet and just use that. Personally I really like the Xorshift+ algorithm: https://en.wikipedia.org/wiki/Xorshift

Link to comment
Share on other sites

Link to post
Share on other sites

To get random number in range in c you need to use this formola

x = (rand()%(max-min + 1)) + min;

 

Holding 10 digit intger is a problem though. Im not sure if long long is a thing in c (I never used it on any language) but it sould hold 10 digit as 1 integer. What I'll do is use malloc for sizeof(short)*10.

 

For this example I'll just use 4 digit numbers:

#include <stdio.h>#include <stdlib.h>#include <time.h> int main(){ int x;srand(time(NULL)); //this line is importent, without it you will get the same numbers every time you run the prgram x = (rand() % (9999 - 1000+ 1)) + 1000); // the max is 9999 and min 1000 printf ("%d", x);    system ("pause");return 0;} 
Link to comment
Share on other sites

Link to post
Share on other sites

Holding 10 digit intger is a problem though. Im not sure if long long is a thing in c (I never used it on any language) but it sould hold 10 digit as 1 integer. What I'll do is use malloc for sizeof(short)*10.

 

long long is indeed a thing in C and it is guaranteed to be at least 64 bits. In Other languages (like Java and C#), long long does not exist, but long is already 64 bits

Link to comment
Share on other sites

Link to post
Share on other sites

The easiest way to make a random number generator is to multiply a seed by a large prime and add another large prime in a loop for a bunch of iterations, then take however many bits you need from your result and scale appropriately.

 

Another way is to XOR by a large prime, then XOR several times by itself bit shifted.

 

I'm not sure how great the entropy of these is, but it's probably fine as long as your don't need anything cryptographically secure.

 

 

That suggestion was pretty stupid, don't do that. Use a Binary mask

#define MASK 0x2540BE3FFrand() & MASK;

 

Why would you use that number as a binary mask instead of (1 << n) - 1?

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×