Author Topic: random function question  (Read 35680 times)

Offline Deamon

  • Multiple posting newcomer
  • *
  • Posts: 27
    • Imperial U Flotilla
random function question
« on: April 03, 2006, 11:33:06 pm »
Hi folks,

under Borland i used the:

randomize();
random(9);

to get a random value betwin 0 and 9 but when i try to compile it under WingW i realize again that it's not ansi compliant. Now my question is how can i achieve the same results in an ansi compliant way ?

regards,
Deamon
IMPERIAL U-FLOTILLA 1914-1918
http://www.nord-com.net/heinrich.lang/sigs/U1-U31_schr%e4g_600x110.jpg
 Current stage: 1 - Planning

Offline takeshi miya

  • Lives here!
  • ****
  • Posts: 1487
Re: random function question
« Reply #1 on: April 03, 2006, 11:36:48 pm »
C version:
Code: C++
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <time.h>
  4.  
  5. srand(time(NULL));
  6. int i;
  7. for(i = 0; i < 10; i++)
  8.     printf("Random number #%d: %d\n", i, rand());
  9.  

C++ version:
Code: C++
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <ctime>
  4.  
  5. std::srand(std::time(0));
  6. for(int i = 0; i < 10; i++)
  7.     std::cout << "Random number #" << i << ": " << std::rand() << std::endl;
  8.  

The function srand() is used to seed the random sequence generated by rand(). For any given seed, rand() will generate a specific "random" sequence over and over again.
« Last Edit: April 04, 2006, 12:29:54 am by Takeshi Miya »

Offline TDragon

  • Lives here!
  • ****
  • Posts: 936
    • Twilight Dragon Media
Re: random function question
« Reply #2 on: April 04, 2006, 12:21:27 am »
In addition to Takeshi's helpful post (neither of your samples will compile, Takeshi :?), allow me to add this:

Code: C++
  1. #include <stdlib.h> // if using C++, #include <cstdlib>; may not be necessary in C
  2. #include <time.h> // if using C++, #include <ctime>
  3.  
  4. // Seed the RNG
  5. srand(time(0));
  6.  
  7. int RandomIntInRange(int low, int high)
  8. {
  9.         return (int)(rand() / (RAND_MAX / (double)(high - low))) + low;
  10. }
  11.  
  12.  
There's probably an unnecessary cast in there, but don't disparage my parentheses -- I use them to indicate my thought processes when I come back to the code a few years down the road.
http://tdm-gcc.tdragon.net/ - TDM-GCC compiler suite for Windows (GCC 5.1.0 2015-06-28, 32/64-bit, no extra DLLs)

Offline takeshi miya

  • Lives here!
  • ****
  • Posts: 1487
Re: random function question
« Reply #3 on: April 04, 2006, 12:31:42 am »
In addition to Takeshi's helpful post (neither of your samples will compile, Takeshi :?)

Sorry, forgot to add #include <time.h> for the first example.
The second example compiles fine, why do you say it'll not compile?

Offline TDragon

  • Lives here!
  • ****
  • Posts: 936
    • Twilight Dragon Media
Re: random function question
« Reply #4 on: April 04, 2006, 12:42:12 am »
Because it didn't #include <ctime> at the time I made my post.
http://tdm-gcc.tdragon.net/ - TDM-GCC compiler suite for Windows (GCC 5.1.0 2015-06-28, 32/64-bit, no extra DLLs)

Offline takeshi miya

  • Lives here!
  • ****
  • Posts: 1487
Re: random function question
« Reply #5 on: April 04, 2006, 12:46:16 am »
Because it didn't #include <ctime> at the time I made my post.
Yup, those things happens. However, it *did* compiled fine in g++.
Somehow, the stdlib++ includes somewhere the function time(), which maked it compile and run fine. :P

Offline TDragon

  • Lives here!
  • ****
  • Posts: 936
    • Twilight Dragon Media
Re: random function question
« Reply #6 on: April 04, 2006, 12:50:55 am »
My apologies; your original C++ sample does indeed compile under MinGW32/GCC (assuming one adds a wrapping main function).
http://tdm-gcc.tdragon.net/ - TDM-GCC compiler suite for Windows (GCC 5.1.0 2015-06-28, 32/64-bit, no extra DLLs)

Offline takeshi miya

  • Lives here!
  • ****
  • Posts: 1487
Re: random function question
« Reply #7 on: April 04, 2006, 01:28:46 am »
My apologies; your original C++ sample does indeed compile under MinGW32/GCC (assuming one adds a wrapping main function).

BTW, I'm very surprised that this compiles fine with no warnings under MinGW32/G++ (compiled with -Wall -W -pedantic):

Code: C++
  1. #include <iostream>
  2.  
  3. int main()
  4. {
  5. srand(time(0));
  6. for(int i = 0; i < 10; i++)
  7.     printf("Random number #%d: %d\n", i, rand());
  8. }

stdlib++'s <iostream> is doing nasty things here. :shock:

Notice how srand(), rand(), and printf(), works without having to include <cstdlib>.
And <iostream> internally must be including <stdlib.h> instead of <cstdlib>, because notice how putting std:: qualifier is not requiered.

Also notice how including <ctime> was not requiered, neither qualifying time() with std::.

Offline Deamon

  • Multiple posting newcomer
  • *
  • Posts: 27
    • Imperial U Flotilla
Re: random function question
« Reply #8 on: April 04, 2006, 01:54:41 am »
#include <stdlib.h> // if using C++, #include <cstdlib>; may not be necessary in C
#include <time.h> // if using C++, #include <ctime>

// Seed the RNG
srand(time(0));

int RandomIntInRange(int low, int high)
{
   return (int)(rand() / (RAND_MAX / (double)(high - low))) + low;
}

Are you sire about it ?

When i compile it it tells me:

main.cpp:20: ISO C++ forbids declaration of `srand' with no type
main.cpp:20: `int srand' redeclared as different kind of symbol
D:/Programme/CodeBlocks/share/CodeBlocks/plugins/compilers/MinGW/include/stdlib.h:362: previous
   declaration of `void srand(unsigned int)'
Process terminated with status 1 (0 minutes, 3 seconds)

When i put it inside RandomIntInRange() or main then it works but why doesn't it work globaly ?

And TDragon, is see you made your own function for random number with a range resolution! Does that mean there is now specialized function for it in the ansi libs ?

Quote
There's probably an unnecessary cast in there, but don't disparage my parentheses -- I use them to indicate my thought processes when I come back to the code a few years down the road.

What ?

regards,
Deamon
IMPERIAL U-FLOTILLA 1914-1918
http://www.nord-com.net/heinrich.lang/sigs/U1-U31_schr%e4g_600x110.jpg
 Current stage: 1 - Planning

Offline TDragon

  • Lives here!
  • ****
  • Posts: 936
    • Twilight Dragon Media
Re: random function question
« Reply #9 on: April 04, 2006, 02:55:37 am »
When i compile it it tells me:

main.cpp:20: ISO C++ forbids declaration of `srand' with no type
main.cpp:20: `int srand' redeclared as different kind of symbol
D:/Programme/CodeBlocks/share/CodeBlocks/plugins/compilers/MinGW/include/stdlib.h:362: previous
   declaration of `void srand(unsigned int)'
Process terminated with status 1 (0 minutes, 3 seconds)

When i put it inside RandomIntInRange() or main then it works but why doesn't it work globaly ?
srand(time(0)); is a function call. Function calls must be inside other functions or used as expressions -- they don't qualify as statements in the global scope. You should place it in your main function or initialization function (if you have one).

Quote
And TDragon, is see you made your own function for random number with a range resolution! Does that mean there is now specialized function for it in the ansi libs ?
That's correct, there is no function in ANSI C that returns a random number within a custom range.

Quote
Quote
There's probably an unnecessary cast in there, but don't disparage my parentheses -- I use them to indicate my thought processes when I come back to the code a few years down the road.
What ?
Nothing. :)
http://tdm-gcc.tdragon.net/ - TDM-GCC compiler suite for Windows (GCC 5.1.0 2015-06-28, 32/64-bit, no extra DLLs)

Offline Deamon

  • Multiple posting newcomer
  • *
  • Posts: 27
    • Imperial U Flotilla
Re: random function question
« Reply #10 on: April 04, 2006, 05:54:15 am »
srand(time(0)); is a function call. Function calls must be inside other functions or used as expressions -- they don't qualify as statements in the global scope.


Oh yeah forgot that we are talking about a function call here LOL

I guess it's late here again :)

Quote
That's correct, there is no function in ANSI C that returns a random number within a custom range.

Bump! That sucks. Man i love the borland guys. They make such usefull stuff. The ansi guys feel the same:

http://tigcc.ticalc.org/doc/stdlib.html#random

And thanks for the help guys. Searched the net and found everything just not what i needed. What is not a miracle cose as you told me there is no specialized function for it. LOL

regards,
Deamon
« Last Edit: April 04, 2006, 05:56:32 am by Deamon »
IMPERIAL U-FLOTILLA 1914-1918
http://www.nord-com.net/heinrich.lang/sigs/U1-U31_schr%e4g_600x110.jpg
 Current stage: 1 - Planning

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1442
    • CenizaSOFT
Re: random function question
« Reply #11 on: April 04, 2006, 04:23:56 pm »
I still wonder why you posted that link to the gcc port for Texas Instruments calcs...

What's so true is how ppl get used to those extra functions provided by Borland :)

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: random function question
« Reply #12 on: April 04, 2006, 07:30:20 pm »
Quote
That's correct, there is no function in ANSI C that returns a random number within a custom range.

Bump! That sucks. Man i love the borland guys. They make such usefull stuff.
Actually that doesn't suck at all. You can write your own trivial wrapper function which fits your needs exactly. It may be arbitrarily precise (like the above one) or abitrarily efficient (like for example using & if you need a less-than-some-power-of-two random).

For example, the above function is guaranteed to return a good random distribution. However, other solutions are possible which are on the order of 2-10 times faster but which might not have the same statistical properties (rand % a + b will for example be about twice as fast, and a construct using & instead of % might be 10-20 times as fast).

For applications which require a good random distribution, using % and & was an extremely bad idea back in the old days (1970-2000), as in the good old standard C generator the lower bits were not random at all (and % isn't either, if you are pedantic)!
Practically every rand() implementation uses MT these days, and most applications don't need perfect distributions, so that is fine either way... :)

If you use whatever the Borland guys made up, then you are bound to whatever they decided was right. This may not be what you want.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline me22

  • Official tester
  • Multiple posting newcomer
  • ***
  • Posts: 53
    • TA Universe
Re: random function question
« Reply #13 on: April 05, 2006, 05:43:52 am »
stdlib++'s <iostream> is doing nasty things here. :shock:

Actually, C++ headers are allowed to include as many or as few other C++ headers as they like, so it's perfectly acceptable for it to do that.  This is the reason why using namespace std; is dangerous (since you have no idea which headers are being brought into scope) and why you are supposed to include the headers declaring anything you use, since you can't even ( technically ) rely on <iostream> including <istream> and <ostream>.

As for the original point of this thread:
Code: [Select]
#include <ctime>
#include <cstdlib>
void randomize() { std::srand( std::time(0) ); }
int random(int upper) { return std::rand()%(upper+1); }
( if you're using C, s/std:://g and s/<c(.+?)>/<$1.h>/g )

Note, however, that the % method of getting random numbers is actually a fairly bad pseudo-random with most crts.

The better way:
Code: [Select]
double random() { std::rand()/(RAND_MAX+1.); }then n*random() will give you a decently pseudo-random number in [0,n)

If you want really good (pseudo-)random numbers, then use http://www.boost.org/libs/random

Offline takeshi miya

  • Lives here!
  • ****
  • Posts: 1487
Re: random function question
« Reply #14 on: April 05, 2006, 06:05:24 am »
stdlib++'s <iostream> is doing nasty things here. :shock:

Actually, C++ headers are allowed to include as many or as few other C++ headers as they like, so it's perfectly acceptable for it to do that. 
It's probable that you didn't read the entire post.
The point is not that <iostream> is bringing to scope (to std::) some C++ headers, but the point is that it is bringing to scope C headers, therefore making really useless the whole C++ headers for std qualifiers (cstdlib, ctime, c*...), and also helping to write non-portable programs.