Thread: Is this a "sound" way to generate a random floating point number?

  1. #1
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901

    Is this a "sound" way to generate a random floating point number?

    I'm basically creating an openGL program where I have to determine the size, alpha, accelleration, and color of particles, so they range in the less than 1 range. I am doing it by generating a larger random number and dividing it by a factor to reduce it to a fraction of the larger number for example

    Code:
    part.size = static_cast<float>(rand() &#37; ((3 - 1) + 1) + 1 ) / 10;  //random size from 1.0 - 3.0
    part.dy =  static_cast<float>(rand() % ((100 - 25) + 1) + 25 ) / 100; //random acceleration from .25 - 1.0
    I was just wondering, I've never really found much information on random numbers, but is there anything flawed about this strategy, any overhead from the calculations, or will this do?
    Last edited by indigo0086; 07-01-2007 at 10:08 PM.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >static_cast<float>(rand() % ((3 - 1) + 1) + 1 ) / 10; //random size from 1.0 - 3.0
    Casting an integer to a float doesn't magically give you precision between the whole numbers. You'll get x.000000 in all cases. This applies to your other statement as well. Neither of them will give you the desired results.
    My best code is written with the delete key.

  4. #4
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    Well it came out pretty good, and I'm getting random numbers that are floats. I only cast the integer result from the rand range, then divided that by the factor to reduce it to a fraction.

    Code:
            part.blue = static_cast<float>(rand() &#37; ((10 - 3) + 1) + 3) / 10;
            part.alpha = static_cast<float>(rand() % ((10 - 5) + 1) + 5 ) / 10;  
            part.size = static_cast<float>(rand() % ((75 - 10) + 1) + 10 ) / 100;  
            part.dy =  static_cast<float>(rand() % ((300 - 25) + 1) + 25)/ 100;
    So far when I render the particles from the code I get visual results similar to what I would expect. I was just wondering if there were downfals to it.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you can remove the static cast and add .0 somewhere in the statement like:
    (rand() &#37; ((10 - 3) + 1) + 3) / 10.0; (this will use double for division)
    or
    (rand() % ((10 - 3) + 1) + 3) / 10.0f ; (floats)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    ok, that works. I don't need that much significance since when drawing a polygon in OpenGL, there is little difference between .4 and .4568482. I just needed something to give me a floating point precision of about two digits at most.

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by indigo0086 View Post
    I'm basically creating an openGL program where I have to determine the size, alpha, accelleration, and color of particles, so they range in the less than 1 range. I am doing it by generating a larger random number and dividing it by a factor to reduce it to a fraction of the larger number for example
    There's nothing wrong with that approach, as long as the underlying random number generator works correctly. You will always have slight quantization errors which shift the distribution away from perfect uniformity, even if the base RNG is perfectly distributed, but in most cases it is unimportant.

    However, your particular method:

    Code:
    part.size = static_cast<float>(rand() % ((3 - 1) + 1) + 1 ) / 10;
    part.dy =  static_cast<float>(rand() % ((100 - 25) + 1) + 25 ) / 100;
    Could probably be improved. Instead of coding this by hand everywhere, write a single function that returns a floating point value in the range [0.0, 1.0). You can do this easily by dividing the output of rand() by RAND_MAX + 1:

    Code:
    float random_unity(void)
    {
        return float(rand()) / (float(RAND_MAX) + 1.0);
    }
    The cast of RAND_MAX to float is important. You can probably figure out why. Using this you can easily get numbers in any given range:

    Code:
    float random_in_range(float min, float max)
    {
        return random_unity() * (max - min) + min;
    }
    Note that you'll never get exactly 1.0 as a result from random_unity(), and accordingly you'll never get exactly "max" from random_in_range(). If you want the range to be fully inclusive, i.e. [0.0, 1.0] instead of [0.0, 1.0), drop the "+ 1" from the denominator in random_unity().

  8. #8
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    Thanks for that solution, didn't think I would need a random utility but it makes it easier since I'm going to want to change the boundary settings and this'll make it more portable.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. floating point number comparison
    By stanlvw in forum C++ Programming
    Replies: 9
    Last Post: 04-27-2009, 01:44 PM
  2. HELP! Changing the base of a floating point number..
    By yigster in forum C Programming
    Replies: 6
    Last Post: 03-27-2008, 05:36 AM
  3. adding a number to a number
    By bigmac(rexdale) in forum C Programming
    Replies: 11
    Last Post: 10-24-2007, 12:56 PM
  4. Replies: 4
    Last Post: 07-14-2003, 08:11 AM
  5. Best way to generate a random double?
    By The V. in forum C Programming
    Replies: 3
    Last Post: 10-16-2001, 04:11 PM