473,513 Members | 3,208 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

rule for promotion

Hi All,
I hope I am posting a C question instead of a C++ this time. I have
the following program:

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

int main(int argc,char** argv){
int i;
srand(time(0));
for(i = 0; i < 20; i++){
int x = 1 + (int) (20.0 * rand() / (RAND_MAX + 1.0));
int y = 1 + (int) (20 * rand() / (RAND_MAX + 1.0));
int z = 1 + (int) (20.0 * rand() / (RAND_MAX + 1 ));
printf("%d %d %d\n",x,y,z);
}
}

and it prints:

12 1 -18
4 1 -17
14 1 -12
17 1 -13
8 1 0
9 1 -2
.... etc

it looks like x is always between 1 and 20. y is always 1 and z is
always between negative and 0. i don't understand why. i guess i
understand why x is always positive because the whole expression is
evaluated in long(?) so there won't be any overflow, right? But is y
and z behave so differently? I though C promote the expression if one
of them is long instead of int, right? Can someone explain what
happened? Thanks!
Nov 14 '05 #1
6 1497

"pembed2003" <pe********@yahoo.com> wrote in message

int z = 1 + (int) (20.0 * rand() / (RAND_MAX + 1 ));
it looks like x is always between 1 and 20. y is always 1 and z is
always between negative and 0. i don't understand why.

The expression rand() / (RAND_MAX + 1) will be evaluated first as an integer
expression. RAND_MAX on your machine must equal INT_MAX, so RAND_MAX + 1 is
the lowest possible negative integer.
Nov 14 '05 #2
In article <c5**********@newsg1.svr.pol.co.uk>,
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:
"pembed2003" <pe********@yahoo.com> wrote in message

int z = 1 + (int) (20.0 * rand() / (RAND_MAX + 1 ));
it looks like x is always between 1 and 20. y is always 1 and z is
always between negative and 0. i don't understand why.

The expression rand() / (RAND_MAX + 1) will be evaluated first as an integer
expression. RAND_MAX on your machine must equal INT_MAX, so RAND_MAX + 1 is
the lowest possible negative integer.


You should really know that this is not true.

20.0 * rand() / (RAND_MAX + 1) is evaluated as follows:

20.0 => Value 20, type double.
rand () => Random value, type int, from 0 to RAND_MAX
(RAND_MAX + 1) => Type int. If RAND_MAX == INT_MAX then -> overflow,
undefined behavior; many implementations will produce INT_MIN.

20.0 * rand () => rand () is converted to double, result is of type
double, from 0 to 20 * RAND_MAX.
20.0 * rand () / (RAND_MAX + 1) => RAND_MAX + 1 is converted to
double. If there was no overflow in calculating RAND_MAX + 1 then the
result is of type double, >= 0.0 and < 20.0. If there is an overflow,
then undefined behavior, but most likely the result of (RAND_MAX + 1) is
INT_MIN, which is often - (INT_MAX + 1) = - (RAND_MAX + 1), so the
result is <= 0 and > -20.
Nov 14 '05 #3
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote in message news:<ch*********************************@slb-newsm1.svr.pol.co.uk>...
In article <c5**********@newsg1.svr.pol.co.uk>,
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:
"pembed2003" <pe********@yahoo.com> wrote in message

int z = 1 + (int) (20.0 * rand() / (RAND_MAX + 1 ));
it looks like x is always between 1 and 20. y is always 1 and z is
always between negative and 0. i don't understand why.

The expression rand() / (RAND_MAX + 1) will be evaluated first as an integer
expression. RAND_MAX on your machine must equal INT_MAX, so RAND_MAX + 1 is
the lowest possible negative integer.


You should really know that this is not true.

20.0 * rand() / (RAND_MAX + 1) is evaluated as follows:

20.0 => Value 20, type double.
rand () => Random value, type int, from 0 to RAND_MAX
(RAND_MAX + 1) => Type int. If RAND_MAX == INT_MAX then -> overflow,
undefined behavior; many implementations will produce INT_MIN.

20.0 * rand () => rand () is converted to double, result is of type
double, from 0 to 20 * RAND_MAX.
20.0 * rand () / (RAND_MAX + 1) => RAND_MAX + 1 is converted to
double. If there was no overflow in calculating RAND_MAX + 1 then the
result is of type double, >= 0.0 and < 20.0. If there is an overflow,
then undefined behavior, but most likely the result of (RAND_MAX + 1) is
INT_MIN, which is often - (INT_MAX + 1) = - (RAND_MAX + 1), so the
result is <= 0 and > -20.


Thanks for the explaination. Here is how I look at it:

(20.0 * rand() / (RAND_MAX + 1 ))

If I put parenthesis:

(((20.0) * (rand())) / ((RAND_MAX) + (1)))

so essentially:

(((double) * (int)) / ((int) + (int)))

double * int gives:

((double) / ((int) + (int)))

now since the second expression overflow (in my machine RAND_MAX ==
MAX_INT), we have:

((doubld) / ((MAX_INT) + (1))) = ((double) / (overflow))

which results in a nagetive number. make sense. But I can't understand
why:

(20 * rand() / (RAND_MAX + 1.0))

always result in a 1?

(((20) * (rand())) / ((RAND_MAX) + (1.0)))

so it's:

(((int) * (int)) / ((int) + (double)))

and then:

(((int) * (int)) / (double))

and then from here, I can't understand why it's always a 1. I can
understand that an int * int might overflow but will C promote it to a
double because we have a double just on the right side of /

Thanks!
Nov 14 '05 #4

On Fri, 15 Apr 2004, pembed2003 wrote:

Christian Bau <ch***********@cbau.freeserve.co.uk> wrote

20.0 * rand() / (RAND_MAX + 1) is evaluated as follows:

20.0 => Value 20, type double.
rand () => Random value, type int, from 0 to RAND_MAX
(RAND_MAX + 1) => Type int. If RAND_MAX == INT_MAX then -> overflow,
undefined behavior; many implementations will produce INT_MIN.

20.0 * rand () => rand () is converted to double, result is of type
double, from 0 to 20 * RAND_MAX.
20.0 * rand () / (RAND_MAX + 1) => RAND_MAX + 1 is converted to
double. If there was no overflow in calculating RAND_MAX + 1 then the
result is of type double, >= 0.0 and < 20.0. If there is an overflow,
then undefined behavior, but most likely the result of (RAND_MAX + 1) is
INT_MIN, which is often - (INT_MAX + 1) = - (RAND_MAX + 1), so the
result is <= 0 and > -20.

[Why does]
(20 * rand() / (RAND_MAX + 1.0))

always result in a 1?
It doesn't, of course. It results in a floating-point 'double'
value, on your machine probably between -1.0 and 1.0 (even though of
course technically it could do whatever it liked).
Consider:

20 --> type 'int', value 20
rand() --> type 'int', value 0..RAND_MAX
20 * rand() --> type 'int', value 0..20*RAND_MAX

Now, at this point we realize that RAND_MAX is probably equal to
INT_MAX (as it is on most modern systems); so 20*RAND_MAX overflows
and we have a case of undefined behavior. Let's assume that 'int'
values overflow by "wrapping around," so that the value of 20*rand()
is still a random number between INT_MIN and INT_MAX.

20 * rand() --> type 'int', value INT_MIN..INT_MAX
RAND_MAX + 1.0 --> type 'double', value RAND_MAX+1
whole expression --> type 'double', value...

The value of the whole expression, assuming what we assumed above about
overflow on your machine, is a random number between
(INT_MIN/(RAND_MAX+1.)) and (INT_MAX/(RAND_MAX+1.)) . And since RAND_MAX
is assumed to be INT_MAX, and we can also assume that on your machine
INT_MIN is just -INT_MAX-1, our resulting value is a 'double' value
between -1.0 and INT_MAX/(INT_MAX+1).
Thanks!


You're welcome.

-Arthur

Nov 14 '05 #5
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote in message news:<ch*********************************@slb-newsm1.svr.pol.co.uk>...
In article <c5**********@newsg1.svr.pol.co.uk>,
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:
"pembed2003" <pe********@yahoo.com> wrote in message

int z = 1 + (int) (20.0 * rand() / (RAND_MAX + 1 ));
it looks like x is always between 1 and 20. y is always 1 and z is
always between negative and 0. i don't understand why.

The expression rand() / (RAND_MAX + 1) will be evaluated first as an integer
expression. RAND_MAX on your machine must equal INT_MAX, so RAND_MAX + 1 is
the lowest possible negative integer.


You should really know that this is not true.

20.0 * rand() / (RAND_MAX + 1) is evaluated as follows:

20.0 => Value 20, type double.
rand () => Random value, type int, from 0 to RAND_MAX
(RAND_MAX + 1) => Type int. If RAND_MAX == INT_MAX then -> overflow,
undefined behavior; many implementations will produce INT_MIN.

20.0 * rand () => rand () is converted to double, result is of type
double, from 0 to 20 * RAND_MAX.
20.0 * rand () / (RAND_MAX + 1) => RAND_MAX + 1 is converted to
double. If there was no overflow in calculating RAND_MAX + 1 then the
result is of type double, >= 0.0 and < 20.0. If there is an overflow,
then undefined behavior, but most likely the result of (RAND_MAX + 1) is
INT_MIN, which is often - (INT_MAX + 1) = - (RAND_MAX + 1), so the
result is <= 0 and > -20.


Thanks for the explaination. Here is how I look at it:

(20.0 * rand() / (RAND_MAX + 1 ))

If I put parenthesis:

(((20.0) * (rand())) / ((RAND_MAX) + (1)))

so essentially:

(((double) * (int)) / ((int) + (int)))

double * int gives:

((double) / ((int) + (int)))

now since the second expression overflow (in my machine RAND_MAX ==
MAX_INT), we have:

((doubld) / ((MAX_INT) + (1))) = ((double) / (overflow))

which results in a nagetive number. make sense. But I can't understand
why:

(20 * rand() / (RAND_MAX + 1.0))

always result in a 1?

(((20) * (rand())) / ((RAND_MAX) + (1.0)))

so it's:

(((int) * (int)) / ((int) + (double)))

and then:

(((int) * (int)) / (double))

and then from here, I can't understand why it's always a 1. I can
understand that an int * int might overflow but will C promote it to a
double because we have a double just on the right side of /

Thanks!
Nov 14 '05 #6

On Fri, 15 Apr 2004, pembed2003 wrote:

Christian Bau <ch***********@cbau.freeserve.co.uk> wrote

20.0 * rand() / (RAND_MAX + 1) is evaluated as follows:

20.0 => Value 20, type double.
rand () => Random value, type int, from 0 to RAND_MAX
(RAND_MAX + 1) => Type int. If RAND_MAX == INT_MAX then -> overflow,
undefined behavior; many implementations will produce INT_MIN.

20.0 * rand () => rand () is converted to double, result is of type
double, from 0 to 20 * RAND_MAX.
20.0 * rand () / (RAND_MAX + 1) => RAND_MAX + 1 is converted to
double. If there was no overflow in calculating RAND_MAX + 1 then the
result is of type double, >= 0.0 and < 20.0. If there is an overflow,
then undefined behavior, but most likely the result of (RAND_MAX + 1) is
INT_MIN, which is often - (INT_MAX + 1) = - (RAND_MAX + 1), so the
result is <= 0 and > -20.

[Why does]
(20 * rand() / (RAND_MAX + 1.0))

always result in a 1?
It doesn't, of course. It results in a floating-point 'double'
value, on your machine probably between -1.0 and 1.0 (even though of
course technically it could do whatever it liked).
Consider:

20 --> type 'int', value 20
rand() --> type 'int', value 0..RAND_MAX
20 * rand() --> type 'int', value 0..20*RAND_MAX

Now, at this point we realize that RAND_MAX is probably equal to
INT_MAX (as it is on most modern systems); so 20*RAND_MAX overflows
and we have a case of undefined behavior. Let's assume that 'int'
values overflow by "wrapping around," so that the value of 20*rand()
is still a random number between INT_MIN and INT_MAX.

20 * rand() --> type 'int', value INT_MIN..INT_MAX
RAND_MAX + 1.0 --> type 'double', value RAND_MAX+1
whole expression --> type 'double', value...

The value of the whole expression, assuming what we assumed above about
overflow on your machine, is a random number between
(INT_MIN/(RAND_MAX+1.)) and (INT_MAX/(RAND_MAX+1.)) . And since RAND_MAX
is assumed to be INT_MAX, and we can also assume that on your machine
INT_MIN is just -INT_MAX-1, our resulting value is a 'double' value
between -1.0 and INT_MAX/(INT_MAX+1).
Thanks!


You're welcome.

-Arthur

Nov 14 '05 #7

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

Similar topics

10
2247
by: Niels Dekker (no reply address) | last post by:
Is it possible for a standard compliant C++ compiler to have ( sizeof(short) < sizeof(int) ) and ( sizeof(short) == sizeof((short)0 + (short)0) ) ? Regards, Niels Dekker...
8
4836
by: BigMan | last post by:
Can someone cite the rules for type promotion in C++? And, in particular, what is the type of the result of adding 2 values of type char?
2
2150
by: Andy | last post by:
Hi... i'm trying to understand the concept of function name overloading in c++. to understand the resolving system it's important to understand the diffrent levels of typecasting (exact match,...
112
4278
by: Carsten Hansen | last post by:
Suppose I'm using an implementation where an int is 16 bits. In the program below, what function is called in the first case, and what is called in the second case? Also, if there is a difference...
16
5100
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. ...
4
1136
by: pachanga | last post by:
Last week, I got a promotion to a higher position with new responsibilities and new supervisor. My supervisor ask me about a new position opening, and I took the position, but I totally forgot to...
8
1319
by: Jon Paul Jones | last post by:
For some time now, I have been looking for a build system for ASP.NET that will merge the file based ease of deployment of classic ASP with the type saftey and prebuilt nature of ASP.NET with...
4
1676
by: gen_tricomi | last post by:
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) on win32 Type "copyright", "credits" or "license()" for more information. **************************************************************** Personal...
21
4081
by: Frederick Gotham | last post by:
I set about trying to find a portable way to set the value of UCHAR_MAX. At first, I thought the following would work: #define UCHAR_MAX ~( (unsigned char)0 ) However, it didn't work for me....
6
13804
by: sarathy | last post by:
Hi, What is integer promotion? How is it different from arithmetic conversion? Regards, Sarathy
0
7254
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7153
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7432
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7519
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5677
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5079
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4743
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
1
796
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
452
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.