473,382 Members | 1,736 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Random Numbers -- why doesn't this piece of code work?

Dear programmers,

Have a look at this function to generate random numbers from 1 to count.
It simply does not work. Well, actually it compiles silently, but then
returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo Linux).

#include <cstdlib> // For random number generator
#include <ctime> // For time function
using namespace std;

inline int random(int count) {
return 1 +
static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
}

I was able to find out that the command _will_ work as it is expected
with out RAND_MAX, but obviously doesn't make any sense, then.

Thanks in advance,
Moritz Beller
--
web http://www.4momo.de
mail momo.beller at t-online dot de
Jul 22 '05 #1
19 2143
On Thu, 3 Jun 2004 19:19:22 +0200, Moritz Beller
<mo*****************@t-online.de> wrote:
Dear programmers,

Have a look at this function to generate random numbers from 1 to count.
It simply does not work. Well, actually it compiles silently, but then
returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo Linux).

#include <cstdlib> // For random number generator
#include <ctime> // For time function
using namespace std;

inline int random(int count) {
return 1 +
static_cast<int>((count*static_cast<long>(rand()) )/(RAND_MAX+1));
}

I was able to find out that the command _will_ work as it is expected
with out RAND_MAX, but obviously doesn't make any sense, then.

Thanks in advance,
Moritz Beller


I haven't thought about your logic, because, given:

#include <iostream>
#include <cstdlib> // For random number generator
#include <ctime> // For time function
using std::cout;
using std::endl;

inline int random(int count) {
return 1 +

static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
}

int main()
{
srand(time(0));
cout << random(10) << endl;
cout << random(100) << endl;
cout << random(1000) << endl;
cout << random(1000) << endl;

return 0;
}
Here's what transpires:

d:\src\learn>g++ --version
g++ (GCC) 3.2.3 (mingw special 20030504-1)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

d:\src\learn>g++ rand.cpp

d:\src\learn>rand
5
49
552
60

(of course, the numbers change)

So I'm not inclined to go looking for the "bug" quite yet. Did you do an
srand() at the start of your test program?
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #2
"Moritz Beller" <mo*****************@t-online.de> wrote in message
news:c9*************@news.t-online.com...
Dear programmers,

Have a look at this function to generate random numbers from 1 to count.
It simply does not work. Well, actually it compiles silently, but then
returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo Linux).

#include <cstdlib> // For random number generator
#include <ctime> // For time function
using namespace std;

inline int random(int count) {
return 1 +
static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
}

I was able to find out that the command _will_ work as it is expected
with out RAND_MAX, but obviously doesn't make any sense, then.

Thanks in advance,
Moritz Beller


You're casting the result of that division to a long, but the division
itself results in a value of at least 0 but less than 1. So, casting it to
a long truncates it to 0, always! I think if you remove the cast to long,
you'll get a better result.

-Howard

"All programmers write perfect code.
....All other programmers write crap."

"I'm never wrong.
I thought I was wrong once,
but I was mistaken."

Jul 22 '05 #3
Moritz Beller wrote:
Dear programmers,

Have a look at this function to generate random numbers from 1 to count.
It simply does not work. Well, actually it compiles silently, but then
returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo Linux).
What do you expect it to return?

#include <cstdlib> // For random number generator
#include <ctime> // For time function
using namespace std;

inline int random(int count) {
return 1 +
static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
}

I was able to find out that the command _will_ work as it is expected
with out RAND_MAX, but obviously doesn't make any sense, then.


It is possible that in your implementation of 'rand' it always returns 0
if unseeded. Besides, you will always get the same sequence of pseudo-
random numbers. You need to use 'srand'.

V
Jul 22 '05 #4
On Thu, 03 Jun 2004 13:37:33 -0400
Victor Bazarov <v.********@comAcast.net> wrote:
Moritz Beller wrote:
Dear programmers,

Have a look at this function to generate random numbers from 1 to
count. It simply does not work. Well, actually it compiles silently,
but then returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo Linux).
What do you expect it to return?


Random numbers from 1 to count.
It is possible that in your implementation of 'rand' it always returns
0 if unseeded. Besides, you will always get the same sequence of
pseudo- random numbers. You need to use 'srand'.


Usage in context:

const int dimLimit = 100;
dimensions srand((unsigned)time(0));
[...]
int rnumber = random(dimLimit);

Moritz Beller
--
web http://www.4momo.de
mail momo.beller at t-online dot de
Jul 22 '05 #5
Moritz Beller wrote:
On Thu, 03 Jun 2004 13:37:33 -0400
Victor Bazarov <v.********@comAcast.net> wrote:

Moritz Beller wrote:
Dear programmers,

Have a look at this function to generate random numbers from 1 to
count. It simply does not work. Well, actually it compiles silently,
but then returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo Linux).
What do you expect it to return?

Random numbers from 1 to count.


numberS ?

It is possible that in your implementation of 'rand' it always returns
0 if unseeded. Besides, you will always get the same sequence of
pseudo- random numbers. You need to use 'srand'.

Usage in context:

const int dimLimit = 100;
dimensions srand((unsigned)time(0));
[...]
int rnumber = random(dimLimit);


I am sorry, perhaps I am dumb or something, but how do you expect it
to return "numberS" (yes, plural form, as you used) if you only call
it _once_? Just a reality check.

V
Jul 22 '05 #6
"Moritz Beller" <mo*****************@t-online.de> wrote in message
news:c9*************@news.t-online.com...

inline int random(int count) {
return 1 +
static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
}


Is it possible that you got the parentheses wrong in your actual code, and
have grouped together the division inside the static_cast<long>? That would
result in 1 + (count * 0), or 1, as the result.

Or, is it possible the this implementation does the division first, and
treats the result of that division as a long (since both operands are
integral), thus resulting in 0 for the division? (Just a wild-assed guess.)
When I get confused about precendence and grouping, I tend to add more
parentheses, just to be sure. You could try adding parentheses around the
multiplication part to be positive that it's multiplying before dividing.

Alternatively, you could try casting the rand() result as a double instead
of a long. (BTW, why *are* you casting as a long there, when you'll be
casting as int at the end anyway? Just to be sure it's big enough?)

-Howard

"All programmers write perfect code.
....All other programmers write crap."

"I'm never wrong.
I thought I was wrong once,
but I was mistaken."
Jul 22 '05 #7
On Thu, 03 Jun 2004 14:05:03 -0400
Victor Bazarov <v.********@comAcast.net> wrote:
Moritz Beller wrote:
On Thu, 03 Jun 2004 13:37:33 -0400
Victor Bazarov <v.********@comAcast.net> wrote:

Moritz Beller wrote:

Dear programmers,

Have a look at this function to generate random numbers from 1 to
count. It simply does not work. Well, actually it compiles

silently,>>but then returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo
Linux).>
What do you expect it to return?

Random numbers from 1 to count.


numberS ?


ouh, I'm so sorry, one number, of course (YALL -- Yet Another Lapsus
Linguae).

Moritz
--
web http://www.4momo.de
mail momo.beller at t-online dot de
Jul 22 '05 #8
Moritz Beller wrote:

static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));


rand() returns an integral type. RAND_MAX is an integral type. When you
divide two integral types the result is an integral type. Since RAND_MAX
+ 1 is always greater than the value returned by rand(), the result of
the division is always 0.

Change the 1 to 1.0 and remove the casts.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #9
On Thu, 03 Jun 2004 15:18:36 -0400, Pete Becker <pe********@acm.org> wrote:
Moritz Beller wrote:

static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));


rand() returns an integral type. RAND_MAX is an integral type. When you
divide two integral types the result is an integral type. Since RAND_MAX
+ 1 is always greater than the value returned by rand(), the result of
the division is always 0.

Change the 1 to 1.0 and remove the casts.


static_cast<int>
(
(
count * static_cast<long>(rand())
)
/
(RAND_MAX+1)
);

Just a public service ;-)
-leor
--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #10
Leor Zolman wrote:

On Thu, 03 Jun 2004 15:18:36 -0400, Pete Becker <pe********@acm.org> wrote:
Moritz Beller wrote:

static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));


rand() returns an integral type. RAND_MAX is an integral type. When you
divide two integral types the result is an integral type. Since RAND_MAX
+ 1 is always greater than the value returned by rand(), the result of
the division is always 0.

Change the 1 to 1.0 and remove the casts.


static_cast<int>
(
(
count * static_cast<long>(rand())
)
/
(RAND_MAX+1)
);

Just a public service ;-)


Too many parentheses. :-( But I'll still bet that changing the 1 to 1.0
and removing the casts "fixes" the problem. The code assumes that
int*int will fit in a long, which ain't necessarily so. Since int and
long are the same size on most systems these days, the casts probably
don't matter. And if RAND_MAX is equal to INT_MAX (as it is with our C
library on 32-bit platforms, for example) then RAND_MAX+1 (which is of
type unsigned) is greater than any value that count*rand() will produce,
and the quotient will be 0.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #11
On Thu, 03 Jun 2004 15:59:21 -0400, Pete Becker <pe********@acm.org> wrote:
Leor Zolman wrote:

On Thu, 03 Jun 2004 15:18:36 -0400, Pete Becker <pe********@acm.org> wrote:
>Moritz Beller wrote:
>>
>> static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
>
>rand() returns an integral type. RAND_MAX is an integral type. When you
>divide two integral types the result is an integral type. Since RAND_MAX
>+ 1 is always greater than the value returned by rand(), the result of
>the division is always 0.
>
>Change the 1 to 1.0 and remove the casts.


static_cast<int>
(
(
count * static_cast<long>(rand())
)
/
(RAND_MAX+1)
);

Just a public service ;-)


Too many parentheses. :-( But I'll still bet that changing the 1 to 1.0
and removing the casts "fixes" the problem. The code assumes that
int*int will fit in a long, which ain't necessarily so. Since int and
long are the same size on most systems these days, the casts probably
don't matter. And if RAND_MAX is equal to INT_MAX (as it is with our C
library on 32-bit platforms, for example) then RAND_MAX+1 (which is of
type unsigned) is greater than any value that count*rand() will produce,
and the quotient will be 0.


Ah yes. RAND_MAX is 0x7FFF on the gcc platform I tested on here; perhaps
it is INT_MAX on the OP's. Now I agree with you. This makes either the
second or third time I've been bitten by this issue, so perhaps I'll
remember about it from now on...
Thanks,
-leor
--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #12
Moritz Beller wrote:
On Thu, 03 Jun 2004 14:05:03 -0400
Victor Bazarov <v.********@comAcast.net> wrote:

Moritz Beller wrote:
On Thu, 03 Jun 2004 13:37:33 -0400
Victor Bazarov <v.********@comAcast.net> wrote:

Moritz Beller wrote:
>Dear programmers,
>
>Have a look at this function to generate random numbers from 1 to
>count. It simply does not work. Well, actually it compiles

silently,>>but then returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo
Linux).>

What do you expect it to return?
Random numbers from 1 to count.


numberS ?

ouh, I'm so sorry, one number, of course (YALL -- Yet Another Lapsus
Linguae).


But then you get your number. If you call this function repeatedly,
you should get numbers that are different. The starting number will
depend on the seeding method you select and the ability of your
generator to be properly seeded.

I used your function with a small driver and it worked fine on VC++.
IIANM, Leor did too, and got good results.

Victor

Victor
Jul 22 '05 #13
Victor Bazarov wrote:

I used your function with a small driver and it worked fine on VC++.
IIANM, Leor did too, and got good results.


Yup. The problem is a subtle platform dependency. The code assumes that
count*(RAND_MAX+1) fits in a long. If RAND_MAX == LONG_MAX it won't
work.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #14
On Thu, 03 Jun 2004 15:18:36 -0400
Pete Becker <pe********@acm.org> wrote:
Moritz Beller wrote:

static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
rand() returns an integral type. RAND_MAX is an integral type. When
you divide two integral types the result is an integral type. Since
RAND_MAX+ 1 is always greater than the value returned by rand(), the
result of the division is always 0.


Resulting from this I concluded what we really need is a double, isn't
it? Here we go:

static_cast<int>((count*static_cast<double>(rand() ))/(RAND_MAX+1.0));
Change the 1 to 1.0 and remove the casts.


Which didn't make any differences at all. (Besides a mass of warnings by
the compiler.)

Moritz Beller
--
web http://www.4momo.de
mail momo.beller at t-online dot de
Jul 22 '05 #15
Moritz Beller wrote:

On Thu, 03 Jun 2004 15:18:36 -0400
Pete Becker <pe********@acm.org> wrote:
Moritz Beller wrote:

static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
rand() returns an integral type. RAND_MAX is an integral type. When
you divide two integral types the result is an integral type. Since
RAND_MAX+ 1 is always greater than the value returned by rand(), the
result of the division is always 0.


Resulting from this I concluded what we really need is a double, isn't
it?


Yes. That's what happens when you change the 1 to 1.0 <g> (of course, I
meant the 1 after RAND_MAX).
Here we go:

static_cast<int>((count*static_cast<double>(rand() ))/(RAND_MAX+1.0));
Get rid of the casts and most of the parentheses. I can't parse this
without devoting more attention to it than I want to. <g> RAND_MAX + 1.0
is of type double, so the compiler promotes the result of rand() to
double when it evaluates rand()/(RAND_MAX+1.0). Similarly, count gets
promoted to double for the multiplication:

return 1 + count * (rand() / (RAND_MAX + 1.0));
Change the 1 to 1.0 and remove the casts.


Which didn't make any differences at all. (Besides a mass of warnings by
the compiler.)


Well, you shouldn't get a mass of warnings, so it sounds like there's
something else going on.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #16
> "Moritz Beller" <mo*****************@t-online.de> wrote
Have a look at this function to generate random numbers from 1 to count.
It simply does not work. Well, actually it compiles silently, but then
returns "1" (Compiler: gcc/++ 3.3.2-r5; Gentoo Linux).
inline int random(int count) {
return 1 +
static_cast<int>((count*static_cast<long>(rand()))/(RAND_MAX+1));
}

"Howard" <al*****@hotmail.com> wrote You're casting the result of that division to a long, but the division
itself results in a value of at least 0 but less than 1. So, casting it to
a long truncates it to 0, always! I think if you remove the cast to long,
you'll get a better result.


That's not how I read it. It looks to me like the cast to long is happening
before the division, even.
Here's the same expression with newlines added:

1 +
static_cast<int>(
(
count*static_cast<long>(rand())
)/(RAND_MAX+1));

Change the parens like this:
1+static_cast<int>( count * (rand() / (RAND_MAX + 1.0)) )
Jul 22 '05 #17
On Thu, 03 Jun 2004 18:24:14 -0400
Pete Becker <pe********@acm.org> wrote:
Moritz Beller wrote:

On Thu, 03 Jun 2004 15:18:36 -0400
Pete Becker <pe********@acm.org> wrote:
rand() returns an integral type. RAND_MAX is an integral type.
When you divide two integral types the result is an integral type.
Since RAND_MAX+ 1 is always greater than the value returned by
rand(), the result of the division is always 0.
Resulting from this I concluded what we really need is a double,
isn't it?


Yes. That's what happens when you change the 1 to 1.0 <g> (of course,
I meant the 1 after RAND_MAX).


Well, not in fact: return 1 +
static_cast<int>((count*(rand()))/(RAND_MAX+1.0));
also returns 1.
Here we go:

static_cast<int>((count*static_cast<double>(rand() ))/(RAND_MAX+1.0)
);


Get rid of the casts and most of the parentheses. I can't parse this
without devoting more attention to it than I want to. <g> RAND_MAX +
1.0 is of type double, so the compiler promotes the result of rand()
to double when it evaluates rand()/(RAND_MAX+1.0). Similarly, count
gets promoted to double for the multiplication:

return 1 + count * (rand() / (RAND_MAX + 1.0));

(...)
Well, you shouldn't get a mass of warnings, so it sounds like there's
something else going on.


Here is the output I get, just to convince you:

ex14_1.cpp: In function `int random(int)':
ex14_1.cpp:13: warning: return to `int' from `double'
ex14_1.cpp:13: warning: argument to `int' from `double'

Moritz
--
web http://www.4momo.de
mail momo.beller at t-online dot de
Jul 22 '05 #18
On 3 Jun 2004 17:57:37 -0700
al*****@my-dejanews.com (Allan W) wrote:
"Howard" <al*****@hotmail.com> wrote
You're casting the result of that division to a long, but the
division itself results in a value of at least 0 but less than 1.
So, casting it to a long truncates it to 0, always! I think if you
remove the cast to long, you'll get a better result.
That's not how I read it. It looks to me like the cast to long is
happening before the division, even.


Yup, right.
Change the parens like this:
1+static_cast<int>( count * (rand() / (RAND_MAX + 1.0)) )


Now we come to logic: I multiplied the result of rand() with count and
then divided it through (RAND_MAX + 1.0) [see 1], whereas you first
divide rand() through (RAND_MAX + 1.0) and then make a multiple of it
with count [2].

Excerpts:
[1](count*static_cast<double>( rand() )) / (RAND_MAX+1.0)

[2]( count * (rand() / (RAND_MAX + 1.0)) )

Moritz
--
web http://www.4momo.de
mail momo.beller at t-online dot de
Jul 22 '05 #19
Moritz Beller wrote:
Well, you shouldn't get a mass of warnings, so it sounds like there's
something else going on.


Here is the output I get, just to convince you:

ex14_1.cpp: In function `int random(int)':
ex14_1.cpp:13: warning: return to `int' from `double'
ex14_1.cpp:13: warning: argument to `int' from `double'


I wouldn't have called that a "mass" of warnings. You're getting two
warnings for the same thing. It's legal and well defined (in this case).
Put in a cast if you must, or shut of the warning.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Ante Perkovic | last post by:
Hi, everybody First, the code: --------------------- $maxNo = 500 $numbers = range (1,$maxNo); srand ((double)microtime()*1000000); shuffle ($numbers); $subarray = array_slice ($numbers, 0,...
28
by: Paul Rubin | last post by:
http://www.nightsong.com/phr/python/sharandom.c This is intended to be less predicable/have fewer correlations than the default Mersenne Twister or Wichmann-Hill generators. Comments are...
3
by: Jim Davidson | last post by:
Here's what I'm trying to do: I have a string with 30 numbers in it. I want to generate a random number between 0 an 30, go to that position in the string and get that number. Here is the code...
3
by: Joe | last post by:
Hi, I have been working on some code that requires a high use of random numbers within. Mostly I either have to either: 1) flip a coin i.e. 0 or 1, or 2) generate a double between 0 and 1. I...
104
by: fieldfallow | last post by:
Hello all, Is there a function in the standard C library which returns a prime number which is also pseudo-random? Assuming there isn't, as it appears from the docs that I have, is there a...
14
by: Anthony Liu | last post by:
I am at my wit's end. I want to generate a certain number of random numbers. This is easy, I can repeatedly do uniform(0, 1) for example. But, I want the random numbers just generated sum up...
12
by: Jim Michaels | last post by:
I need to generate 2 random numbers in rapid sequence from either PHP or mysql. I have not been able to do either. I get the same number back several times from PHP's mt_rand() and from mysql's...
9
by: Chelong | last post by:
Hi All I am using the srand function generate random numbers.Here is the problem. for example: #include<iostream> #include <time.h> int main() {
16
by: jason.cipriani | last post by:
I am looking for a random number generator implementation with the following requirements: - Thread-safe, re-entrant. - Produces consistently reproducible sequences of psuedo-random numbers...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.