I noticed something with rand and I'm looking for some explanation.

Discussion in 'C Programming' started by mulligan.kyle@gmail.com, Mar 8, 2013.

  1. Guest

    Hello, I am taking an introductory course in C and had an assignment recently that involved rand(). I noticed something interesting and was hoping someone might be able to explain.

    My program allows the user to input an upper and lower floating point boundand my randBetween function returns a floating point number between those two bounds. My program works, however I noticed something strange when dealing with large numbers. For small numbers for my bounds, with a small range, the number printed would have several values after the decimal. However, for large numbers as my bounds with a similar range, only a few actual numbers are printed after the decimal followed by several 0's.

    Here are some examples of outputs:

    enter lower and upper limits separated by a comma: 20,33
    Your random number is 30.922440
    (the range between these bounds is 13)

    enter lower and upper limits separated by a comma: 1234567,1234575
    Your random number is 1234573.750000
    (the range between these bounds is also 13 but less numbers are printed after the decimal)

    Here is my program, please note that I understand how to seed the rand function but chose not to, however I did some testing with multiple seeds.

    -Kyle

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

    float randomBetween(float, float);

    main()
    {
    float userInput1,
    userInput2,
    randomNumber;
    printf("enter lower and upper limits separated by a comma: ");
    scanf("%g,%g", &userInput1,&userInput2);
    randomNumber=randomBetween(userInput1, userInput2);
    printf("Your random number is %f\n", randomNumber);
    }




    float randomBetween(float userInput1,float userInput2)
    {
    float random,
    randomNumber,
    range;
    random = ((float) rand()) / (float) RAND_MAX; /* casts the rand output into float and the RAND_MAX into float so that a random floating point number between 0 and 1 is store$
    range = userInput2-userInput1; /* stores the difference between the two inputs in order for a random number to be created between the two bounds */
    randomNumber = (userInput1 + (random * range)); /* adds the random numberto the lower bound so that the final output is between the bounds */
    return randomNumber;
    }
     
    , Mar 8, 2013
    #1
    1. Advertising

  2. Joe Pfeiffer Guest

    writes:

    > Hello, I am taking an introductory course in C and had an assignment recently that involved rand(). I noticed something interesting and was hoping someone might be able to explain.
    >
    > My program allows the user to input an upper and lower floating point bound and my randBetween function returns a floating point number between those two bounds. My program works, however I noticed something strange when dealing with large numbers. For small numbers for my bounds, with a small range, the number printed would have several values after the decimal. However, for large numbers as my bounds with a similar range, only a few actual numbers are printed after the decimal followed by several 0's.
    >
    > Here are some examples of outputs:
    >
    > enter lower and upper limits separated by a comma: 20,33
    > Your random number is 30.922440
    > (the range between these bounds is 13)
    >
    > enter lower and upper limits separated by a comma: 1234567,1234575
    > Your random number is 1234573.750000
    > (the range between these bounds is also 13 but less numbers are printed after the decimal)


    It's because of the representation of a floating point number in the
    computer. Floats use what amounts to the binary equivalent of
    scientific notation, i.e.

    1.m * 2^e

    where 'm' is the significand and 'e' is the exponent. Without going into
    details, you've only 23 bits of significand; if you've got a small
    number then you'll have many of them to the right of the decimal point,
    and if you've got a large number you'll have many of them to the left of
    the decimal point and hence fewer to the right.
     
    Joe Pfeiffer, Mar 8, 2013
    #2
    1. Advertising

  3. Noob Guest

    mulligan.kyle wrote:

    > Hello, I am taking an introductory course in C and had an assignment
    > recently that involved rand(). I noticed something interesting and
    > was hoping someone might be able to explain.


    I suppose you've already skimmed the Wikipedia entry?
    https://en.wikipedia.org/wiki/Floating_point

    Also, you might want to use "double" instead of "float".
     
    Noob, Mar 8, 2013
    #3
  4. Eric Sosman Guest

    On 3/8/2013 1:20 PM, Noob wrote:
    > mulligan.kyle wrote:
    >
    >> Hello, I am taking an introductory course in C and had an assignment
    >> recently that involved rand(). I noticed something interesting and
    >> was hoping someone might be able to explain.

    >
    > I suppose you've already skimmed the Wikipedia entry?
    > https://en.wikipedia.org/wiki/Floating_point
    >
    > Also, you might want to use "double" instead of "float".


    That may only help a little, and perhaps not at all. Bear
    in mind that rand() can return at most 1+RAND_MAX distinct values,
    so any printed precision beyond log10(1+RAND_MAX) decimal digits
    is an illusion. RAND_MAX is often equal to INT_MAX which in turn
    is often 0x7FFFFFFF, for 9-and-change decimal digits; `float' can
    often handle 7-and-change (the Standard requires at least 6), so
    switching to `double' might gain only two decimal places.

    ... and perhaps not even that much. RAND_MAX can be as small
    as 32767, in which case a rand() value would be worth only four and
    a half decimal digits. In that case, switching from `float' to
    `double' would gain no precision at all -- even if you printed the
    value to lots and lots of places, most would be meaningless.

    --
    Eric Sosman
    d
     
    Eric Sosman, Mar 8, 2013
    #4
  5. Noob Guest

    Eric Sosman wrote:
    > On 3/8/2013 1:20 PM, Noob wrote:
    >> mulligan.kyle wrote:
    >>
    >>> Hello, I am taking an introductory course in C and had an assignment
    >>> recently that involved rand(). I noticed something interesting and
    >>> was hoping someone might be able to explain.

    >>
    >> I suppose you've already skimmed the Wikipedia entry?
    >> https://en.wikipedia.org/wiki/Floating_point
    >>
    >> Also, you might want to use "double" instead of "float".

    >
    > That may only help a little, and perhaps not at all.


    Au contraire, mon ami! ;-)

    Suppose he plans to generate random floating-point values between
    1e9 and 1e9+1. How well is that float gonna work for him? :-þ

    A related exercise is finding the smallest positive float value f
    for which f == f+1 (and understanding why, of course).

    I agree with the general feeling that floating-point numbers are
    a tricky devious bunch, and I stay away from 'em as much as I can.

    And this is where I drop the killer link to the article I've never
    had the patience/courage to read top-to-bottom.

    What Every Computer Scientist Should Know About Floating-Point Arithmetic
    http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

    Regards.
     
    Noob, Mar 8, 2013
    #5
  6. Ian Collins Guest

    Noob wrote:
    > Eric Sosman wrote:
    >> On 3/8/2013 1:20 PM, Noob wrote:
    >>> mulligan.kyle wrote:
    >>>
    >>>> Hello, I am taking an introductory course in C and had an assignment
    >>>> recently that involved rand(). I noticed something interesting and
    >>>> was hoping someone might be able to explain.
    >>>
    >>> I suppose you've already skimmed the Wikipedia entry?
    >>> https://en.wikipedia.org/wiki/Floating_point
    >>>
    >>> Also, you might want to use "double" instead of "float".

    >>
    >> That may only help a little, and perhaps not at all.

    >
    > Au contraire, mon ami! ;-)
    >
    > Suppose he plans to generate random floating-point values between
    > 1e9 and 1e9+1. How well is that float gonna work for him? :-þ


    I think you missed (as well as snipped!) Eric's point. This box
    (Solaris) has RAND_MAX = 32767, so switching to double would gain nothing.

    --
    Ian Collins
     
    Ian Collins, Mar 8, 2013
    #6
  7. Eric Sosman Guest

    On 3/8/2013 6:54 PM, Ian Collins wrote:
    > Noob wrote:
    >> Eric Sosman wrote:
    >>> On 3/8/2013 1:20 PM, Noob wrote:
    >>>> mulligan.kyle wrote:
    >>>>
    >>>>> Hello, I am taking an introductory course in C and had an assignment
    >>>>> recently that involved rand(). I noticed something interesting and
    >>>>> was hoping someone might be able to explain.
    >>>>
    >>>> I suppose you've already skimmed the Wikipedia entry?
    >>>> https://en.wikipedia.org/wiki/Floating_point
    >>>>
    >>>> Also, you might want to use "double" instead of "float".
    >>>
    >>> That may only help a little, and perhaps not at all.

    >>
    >> Au contraire, mon ami! ;-)
    >>
    >> Suppose he plans to generate random floating-point values between
    >> 1e9 and 1e9+1. How well is that float gonna work for him? :-þ

    >
    > I think you missed (as well as snipped!) Eric's point. This box
    > (Solaris) has RAND_MAX = 32767, so switching to double would gain nothing.


    Actually, I think Noob has a point: If the desired values
    are of the form HugeConstant+TinyRandom, the greater precision
    of `double' will help postpone the inevitable losses.

    Of course, if HugeConstant is sufficiently large it will
    drown any TinyRandom, even in `double' or `long double' or
    `long long really really long double' (C21). Noob's point,
    then, is that extended precision can hide -- for a while --
    a bad choice of algorithm. It's folly to measure the distance
    to the Lesser Magellanic Cloud and then add a centimeter.

    --
    Eric Sosman
    d
     
    Eric Sosman, Mar 9, 2013
    #7
  8. Ian Collins wrote:
    > Noob wrote:
    >> Eric Sosman wrote:
    >>> On 3/8/2013 1:20 PM, Noob wrote:
    >>>> mulligan.kyle wrote:
    >>>>
    >>>>> Hello, I am taking an introductory course in C and had an assignment
    >>>>> recently that involved rand(). I noticed something interesting and
    >>>>> was hoping someone might be able to explain.
    >>>>
    >>>> I suppose you've already skimmed the Wikipedia entry?
    >>>> https://en.wikipedia.org/wiki/Floating_point
    >>>>
    >>>> Also, you might want to use "double" instead of "float".
    >>>
    >>> That may only help a little, and perhaps not at all.

    >>
    >> Au contraire, mon ami! ;-)
    >>
    >> Suppose he plans to generate random floating-point values between
    >> 1e9 and 1e9+1. How well is that float gonna work for him? :-þ

    >
    > I think you missed (as well as snipped!) Eric's point. This box
    > (Solaris) has RAND_MAX = 32767, so switching to double would gain nothing.
    >


    I guess the OP could use multiple invocations of rand() to get at as
    many bits of randomness that are required for the specified range...
     
    Johann Klammer, Mar 9, 2013
    #8
  9. Eric Sosman Guest

    On 3/8/2013 11:37 PM, Johann Klammer wrote:
    > [... how much entropy does rand() generate? ...]
    > I guess the OP could use multiple invocations of rand() to get at as
    > many bits of randomness that are required for the specified range...


    When you combine N successive pseudo-random values to form
    a higher-precision result, you have to be concerned about the
    N-dimensional spectral characteristics of the original generator.
    For example, with a maximum-period linear congruential generator
    successive results alternate between odd and even values. If you
    combine these in pairs to get your lengthier result, you'll find
    that one of your result bits is always zero and another is always
    one (before scaling and whatever): two bits' worth of randomness
    have "disappeared."

    The Standard does not say what algorithm rand() should use
    (the example is only an example, not a prescription), so we don't
    know much about how N-apart values may be correlated. Even the
    statistical properties of 1-apart values are a mystery. If you
    need pseudo-random numbers with known "goodness," you'll need to
    code (or borrow) another RNG rather than relying on rand().

    --
    Eric Sosman
    d
     
    Eric Sosman, Mar 9, 2013
    #9
  10. Robert Wessel <> writes:
    [...]
    > Since rand() is specifically defined to be deterministic, you can't
    > get more "random" bits out of it than there is internal state. Which,
    > for the common one defined in the C standard, is 32 bits.


    That's true for common modern implementations of the C standard.
    The seed argument to srand() is an unsigned int, which could be as
    narrow as 16 bits; there's no upper bound, but the widest I've seen
    is 64 bits.

    Still, there are times when it can make sense to generate more
    pseudo-random bits that the size of the internal state. For example,
    if you're plotting random points, having too few bits per sample can
    produce visible non-randomness. By using more bits, you can make
    the plotted points *look* more random, even if they're really not.
    (If you want something closer to true randomness, rand() is not
    the answer.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 10, 2013
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sreekant
    Replies:
    1
    Views:
    271
    sreekant
    Jul 18, 2003
  2. Justin E. Miller

    Anyone else noticed this issue?

    Justin E. Miller, Mar 7, 2008, in forum: HTML
    Replies:
    2
    Views:
    352
    Toby A Inkster
    Mar 7, 2008
  3. Andrea Francia
    Replies:
    1
    Views:
    260
    Albert Hopkins
    Mar 29, 2009
  4. James Harris
    Replies:
    4
    Views:
    471
    Andy Botterill
    Feb 18, 2010
  5. 7stud --

    rand() v. rand(0.1) ?

    7stud --, Sep 15, 2007, in forum: Ruby
    Replies:
    6
    Views:
    270
    Morton Goldberg
    Sep 16, 2007
Loading...

Share This Page