PDA

View Full Version : z = 1. - 2.*RANDNBR


tbaypaul
03-08-2007, 04:03 PM
Just starting to learn procedural texturing and I'm running into this expression.
z = 1. - 2.*RANDNBR
I don't know exactly what it means. The procedure initializes a gradient noise table

I have interperted it as (simple math) the result of a bitwise "and" divided by the RANDMASK as a double.

Then z = 1.0 - 2.0 * RANDNBR which yields a double. Or is another bit operation using the the hex address somehow?

I checked the book's web site for errata, but found none specific to this bit.



include <math.h>
#define RANDMASK 0x7fffffff
#define RANDNBR ((random() & RANDMASK) / (double) RANDMASK
......
gradientTabInit(int seed)
{
......
srandom(seed)
......
z = 1. - 2.*RANDNBR
......
}

nurcc
03-08-2007, 05:10 PM
Basically, he's zeroing out certain bits of the random integer, effectively changing the maximum possible random value from 0xffffffff to 0x7fffffff. I'm not sure exactly why, but that's what's going on. Then he's normalizing the actual random number by dividing by the maximum possible value, changing the range to [0..1]. The output of the macro expression will be a double.

One possibility why he's changing the max range is that some pseudorandom number generators produce more randomness in some bits than in other bits, so he might be trying to maximize randomness, or bias the distribution in some other way. Or, he might have had issues with overflow? Not sure.

tbaypaul
03-08-2007, 08:43 PM
yeah, that part is easy.....but why the 1. - 2. *RANDNBR ...why the notation....it is very explicit in the text and not mentioned in errata.....ie why not.... 1.0 - 2.0 * RANDNBR... he seems to be using pointer notation and leaving out the decimal places but retaining the decimal points.....and it is used in several places thoughout Darwyn Peachy's text.

It's almost like he is converting and amending the hex address to 2. so you have 2.985648475 and then subtracting from 1 . Harnesing the randomizing power of your RAM???maybe???

Robert Bateman
03-08-2007, 11:56 PM
It's almost like he is converting and amending the hex address to 2. so you have 2.985648475 and then subtracting from 1 . Harnesing the randomizing power of your RAM???maybe???

nope. RANDNBR generates a new random number (a double) between 0 and 1. This has nothing to do with hex, he is simply saying

n = 1.0 - (2.0 * (RANDNBR));

so, we could get

n = 1.0 - (2.0 * 0.0) == 1.0

or

n = 1.0 - (2.0*1.0) == -1.0

or any number in between -1 and 1.

The 0x7fffffff is a dirty trick. 0x7fffffff is the largest possible (32bit) integer value. however, 0xffffffff is the smallest possible integer value (the highest bit in an int is the minus sign. therefore, 0xffffffff == -0x7fffffff, ie the lowest negative number possible).

So, the quick way to strip that out, is to mask out the minus sign with an AND bitwise operation (&). Just check the 0x7f and 0xff in binary and it should make sense :

0x7f == 01111111 == 127
0xff == 11111111 == -127

perform a bitwise and and you get :

0x7f == 01111111 == +127

so,

(random() & RANDMSK)

ensures you get a positive number.

(random() & RANDMSK) / RANDMSK

would give you 1 or 0 (since it's an integer division, and disregards the decimal place). So, to fix that problem, we tell the compiler to divide by a double to keep the decimal :

(random() & RANDMSK) / (double)RANDMSK

however, all of that is moot anyway, since if his random() function returns all possible int values, he could have just done :

z = random() / (double)RANDMSK;

which would return a double between -1 to 1 anyway. I think he's just trying to seem clever, but failing ;)

tbaypaul
03-09-2007, 07:51 PM
thanks...that's exactly what I needed to hear.....-1 to 1 is exactly what I'm after....don't know why I got hung up on the typo....I guess cause it is repeated and the material is new to me.

scorpion007
03-09-2007, 11:41 PM
yeah, that part is easy.....but why the 1. - 2. *RANDNBR ...why the notation....it is very explicit in the text and not mentioned in errata.....ie why not.... 1.0 - 2.0 * RANDNBR...
Note that 2. is equivalent to 2.0.
And 2.f is a float version of 2.0 (which is a double)

CGTalk Moderation
03-09-2007, 11:41 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.