Math.random() and Math.round(Math.random()) and Math.floor(Math.random()*2)

Discussion in 'Javascript' started by VK, May 1, 2010.

  1. VK

    VK Guest

    Assuming one needs to have a function returning false or true on each
    call in pseudo-random order.and using JavaScript native Math.random()
    method as the basis of the pseudo-randomness. Say the variants of such
    function are:

    getAnswer1() {
    var n = Math.round(Math.random());
    return n ? true : false;
    }

    getAnswer2() {
    var n = Math.floor(Math.random()*2);
    return (n==2) ? true : false;
    }

    Leaving obvious practical testing by platforms aside:

    Is there are theoretical considerations that pseudo-randomness
    (predictability) of either of above will be better or worse than the
    other one? JavaScript Kit site claims that the second bits first:
    http://www.javascriptkit.com/javatutors/randomnum.shtml
    but they don't disclose the underlaying reasoning.
    VK, May 1, 2010
    #1
    1. Advertising

  2. VK

    Ry Nohryb Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 9:54 am, VK <> wrote:
    > Assuming one needs to have a function returning false or true on each
    > call in pseudo-random order.and using JavaScript native Math.random()
    > method as the basis of the pseudo-randomness. Say the variants of such
    > function are:
    >
    > getAnswer1() {
    >  var n = Math.round(Math.random());
    >  return n ? true : false;
    >
    > }
    >
    > getAnswer2() {
    >  var n = Math.floor(Math.random()*2);
    >  return (n==2) ? true : false;
    >
    > }
    >
    > Leaving obvious practical testing by platforms aside:
    >
    > Is there are theoretical considerations that pseudo-randomness
    > (predictability) of either of above will be better or worse than the
    > other one? JavaScript Kit site claims that the second bits first:
    >  http://www.javascriptkit.com/javatutors/randomnum.shtml
    > but they don't disclose the underlaying reasoning.


    Why not { return Math.random() >= 0.5; } ?
    --
    Jorge.
    Ry Nohryb, May 1, 2010
    #2
    1. Advertising

  3. VK

    VK Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 1:30 pm, Ry Nohryb <> wrote:
    > On May 1, 9:54 am, VK <> wrote:
    >
    >
    >
    > > Assuming one needs to have a function returning false or true on each
    > > call in pseudo-random order.and using JavaScript native Math.random()
    > > method as the basis of the pseudo-randomness. Say the variants of such
    > > function are:

    >
    > > getAnswer1() {
    > >  var n = Math.round(Math.random());
    > >  return n ? true : false;

    >
    > > }

    >
    > > getAnswer2() {
    > >  var n = Math.floor(Math.random()*2);
    > >  return (n==2) ? true : false;

    >
    > > }

    >
    > > Leaving obvious practical testing by platforms aside:

    >
    > > Is there are theoretical considerations that pseudo-randomness
    > > (predictability) of either of above will be better or worse than the
    > > other one? JavaScript Kit site claims that the second bits first:
    > >  http://www.javascriptkit.com/javatutors/randomnum.shtml
    > > but they don't disclose the underlaying reasoning.

    >
    > Why not { return Math.random() >= 0.5; } ?


    I have no idea. The linked source at
    http://www.javascriptkit.com/javatutors/randomnum.shtml
    claims this: "Some of you may be curious as to why Math.floor(),
    instead of Math.round(), is used in the above code. While both
    successfully round off its containing parameter to an integer within
    the designated range, Math.floor does so more "evenly", so the
    resulting integer isn't lopsided towards either end of the number
    spectrum. In other words, a more random number is returned using
    Math.floor()."

    It may be some actual behavior or an author's fantasy - no arguments
    are given on the page. From the Math.round and Math.floor methods
    descriptions:

    https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Math/Round
    Returns the value of a number rounded to the nearest integer.

    https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Math/Floor
    Returns the largest integer less than or equal to a number.

    I am failing to grasp the exact difference between of them. I only
    assume that the only place of rounding inequality results could be in
    "border cases" like 0.5xxxxxx etc. so with .5 being the first
    fractional digit. Respectively if such inequality really exists then
    there must be something with pseudo-random generation in whole or in
    how it is implemented in Math.random() that would suggest 0.5xxxxx or
    0.5 generation being lesser random than other results. Or it is just
    another urban legend.
    VK, May 1, 2010
    #3
  4. VK

    VK Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 1:49 pm, VK <> wrote:
    >  https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Object....
    >  Returns the value of a number rounded to the nearest integer.
    >
    >  https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Object....
    >  Returns the largest integer less than or equal to a number.
    >
    > I am failing to grasp the exact difference between of them. I only
    > assume that the only place of rounding inequality results could be in
    > "border cases" like 0.5xxxxxx etc. so with .5 being the first
    > fractional digit. Respectively if such inequality really exists then
    > there must be something with pseudo-random generation in whole or in
    > how it is implemented in Math.random() that would suggest 0.5xxxxx or
    > 0.5 generation being lesser random than other results. Or it is just
    > another urban legend.


    Another direction to look for is that the computer pseudo-random
    generation operates in non-closed properly set [0,1[ with the upper
    border not included so the result can be 0 but never 1. That shifts
    the predictability pattern down toward 0. This is why actually why
    Shannon's Clairvoyant can quickly tell for any sequence is it's truly
    random or pseudo-random. btw Wiki's http://en.wikipedia.org/wiki/Pseudorandom_function_family
    claim that "No efficient algorithm can distinguish (with significant
    advantage) between a function chosen randomly from the PRF family" is
    a complete b.s. but I am too lazy to argue with the entire ACM. Let
    them believe what they want to believe.

    So it might be that Math.floor somehow "re-balance" the outcome making
    it lesser predictable. I just don't see how could it be. I am really
    puzzled... Maybe I should get all JavaScript stuff out and post it as
    a purely math question to sci.math
    VK, May 1, 2010
    #4
  5. VK

    VK Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 2:20 pm, VK <> wrote:
    > So it might be that Math.floor somehow "re-balance" the outcome making
    > it lesser predictable. I just don't see how could it be. I am really
    > puzzled... Maybe I should get all JavaScript stuff out and post it as
    > a purely math question to sci.math


    Posted at sci.math as a mathematical problem:
    http://groups.google.com/group/sci.math/browse_frm/thread/5846c8a74170acfd
    VK, May 1, 2010
    #5
  6. VK

    Henry Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    VK wrote:
    >On May 1, 1:30 pm, Ry Nohryb wrote:
    >> On May 1, 9:54 am, VK wrote:
    >>> Assuming one needs to have a function returning false or true
    >>> on each call in pseudo-random order.and using JavaScript native
    >>> Math.random() method as the basis of the pseudo-randomness. Say
    >>> the variants of such function are:

    >>
    >>> getAnswer1() {
    >>> var n = Math.round(Math.random());
    >>> return n ? true : false;

    ><snip>
    >> Why not { return Math.random() >= 0.5; } ?

    >
    > I have no idea. The linked source at
    > http://www.javascriptkit.com/javatutors/randomnum.shtml
    > claims this: "Some of you may be curious as to why Math.floor(),
    > instead of Math.round(),


    Given that there has been a prevalence of examples of javascript (so-
    called) random number generators posted to the web that did use
    Math.round and did then produce a non-even distribution of numbers in
    their output, a fair number of readers of that article may well be
    curious about its author's choice.

    > is used in the above code. While both successfully round off
    > its containing parameter to an integer within the designated
    > range,


    This bit isn't actually true as if you did a direct substitute of -
    Math.round - for - Math.floor - then the range of the output would
    increase by one.

    > Math.floor does so more "evenly", so the resulting integer
    > isn't lopsided towards either end of the number spectrum.


    "Lopsided" is probably inappropriate as well, as the output
    distribution following a substitution of - Math.random - for -
    Math.floor - is still symmetrical.

    > In other words, a more random number is returned using
    > Math.floor()."
    >
    > It may be some actual behavior or an author's fantasy


    Most likely an overlay hurried explanation of a common fault in
    javascript authoring, with a couple of mistakes getting in the way of
    making the point.

    > - no arguments are given on the page. From the Math.round
    > and Math.floor methods descriptions:
    >
    > https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Math/Round
    > Returns the value of a number rounded to the nearest integer.
    >
    > https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Math/Floor
    > Returns the largest integer less than or equal to a number.
    >
    > I am failing to grasp the exact difference between of them.


    Then you are the author of:-

    <URL: http://groups.google.com/group/comp..._frm/thread/b495b4898808fde0/63c2ad2bdbdf0b40
    >


    - so we know the subtleties of rounding in javascript don't have to
    get that subtle before you cannot comprehend them.

    > I only assume ...

    <snip>

    Don't waste you time in assuming. The best you will do is invent an
    elaborate fantasy explanation. Just wait for someone to tell you the
    answer, and then avoid ever trying to put it into your own words.

    Richard.
    Henry, May 1, 2010
    #6
  7. VK

    VK Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 3:16 pm, "Richard Cornford" <>
    wrote:
    > You leave practical testing aside far to often in your posted code. Any
    > reasonable testing (or your just understanding the methods/operations
    > employed) would observe that your proposed - getAnswer2 - function only
    > ever returns false. Thus, it fails to satisfy your "returning false or
    > true on each call in pseudo-random order".


    Yeah... My mind was distracted a lot by the binary trees observations,
    sorry.

    > > Is there are theoretical considerations that pseudo-randomness
    > > (predictability) of either of above will be better or worse than
    > > the other one?

    >
    > Yes, but mostly because the obvious bugs in the second prevent it from
    > doing anything useful at all.
    >
    > > JavaScript Kit site claims that the second bits first:
    > >http://www.javascriptkit.com/javatutors/randomnum.shtml
    > > but they don't disclose the underlaying reasoning.

    >
    > The subject of the comments on that page is the choice of the use of
    > Math.floor over Math.round (where Math.round is commonly used in example
    > javascript random number generators found on the Internet).
    >
    > Math.random returns a (pseudo-random) number that is in the range zero
    > to less than one (i.e. anything non-negative that is smaller than one).
    > If you multiply that number by an integer you will get a result that is
    > in the range from zero to less than that number. If two were taken as an
    > example of such a number (i.e. - (Math.random * 2) - the result would be
    > a number in the range zero to less than two.
    >
    > If you apply - Math.round - to all the numbers in the range zero to less
    > than two the range zero to <0.5 (a quarter of the total range) would
    > result in zero, between 0.5 and <1.5 (half the total range) would result
    > in one, and 1.5 to <2 would result in two. So, using Math.round, a
    > random number in the 0 to <2 range has a 25% chance of coming our zero,
    > a 50% chance of coming out one and a 25% chance of coming out 2. This is
    > not an even distribution. (Extending this to multiplying by any positive
    > integer; it is the values at the two extremes of output that end up
    > being half as likely in the output as any numbers in between, however if
    > that integer were one then there would be no numbers in between the
    > extremes of the range and so then the distribution between zero and one
    > would be equal.)
    >
    > If you apply - Math.floor - to numbers in the range 0 to <2 then the
    > range 0 to <1 (half the original range) result in 0 and the range 1 to
    > <2 (the other half of the original range) result in 1; a 50/50
    > distribution.


    Right. Similar answer from sci.math :
    http://groups.google.com/group/sci.math/msg/5a878f7a0aea0b90

    <quote>
    Reply concerning this page, and not your description.

    Let X be uniformly distributed in [0,1). Then floor(X*11) takes
    values
    0,1,...,10 each with probability 1/11 ... that is what the page means
    by "even". However round(X*10) takes value 0 with probability 1/20,
    values 1,...,9 each with probability 1/10 and value 10 with
    probability
    1/20. Not "even" according to the page.
    </quote>

    So the question is then
    a) if it is possible to use Math.floor for a pseudo-random input to
    get binary output (1/0, true/false)
    b) if so than will it be more even probability for output than for
    Math.round(Math.random()) or (Math.random >= 0.5)

    .... or Math.floor(Math.random()*N) benefits appear only for ternary
    and wider ranges "0 or 1 or 2", "0 or 1 or 2 or 3" etc. ?
    VK, May 1, 2010
    #7
  8. VK

    VK Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 3:37 pm, Henry <> wrote:
    > > It may be some actual behavior or an author's fantasy

    >
    > Most likely an overlay hurried explanation of a common fault in
    > javascript authoring, with a couple of mistakes getting in the way of
    > making the point.


    Not so. A probability theory outcome: see my answer to Richard
    Cornford

    > >https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Object...
    > > Returns the value of a number rounded to the nearest integer.

    >
    > >https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Object...
    > > Returns the largest integer less than or equal to a number.

    >
    > > I am failing to grasp the exact difference between of them.

    >
    > Then you are the author of:-
    >
    > <URL:http://groups.google.com/group/comp.lang.javascript/browse_frm/thread...
    >
    >
    >
    > - so we know the subtleties of rounding in javascript don't have to
    > get that subtle before you cannot comprehend them.


    First of all that was about IEEE-754 FP-DP rounding and calculation
    vs. top level methods - not about the probability theory and how does
    it apply to JavaScript Math methods. And yes, I couldn't grasp how
    Math.floor would be more "even probability-friendly" than Math.round
    until I got explanations of that. I don't see you grasping it on the
    spot as your answer is silent about it. At least your first guess
    quoted at the top was wrong.
    VK, May 1, 2010
    #8
  9. VK

    VK Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 4:02 pm, "Richard Cornford" <>
    wrote:
    > >... or Math.floor(Math.random()*N) benefits appear only for ternary
    > >and wider ranges "0 or 1 or 2", "0 or 1 or 2 or 3" etc. ?

    >
    > The issue only applies to rages with more than two values in them. But
    > still, Jorge's remains the better implementation for javascript (FPU
    > handled math operation over a method call), and it uses neither
    > Math.round nor Math.floor.


    Then would it be properly to state that in order to have the least
    compromised pseudo-random sequence of integers from a set of two
    elements one should use
    return (Math.random() >= 0.5) ? _this : _that;
    and for all sets with more than two elements one should use
    return Math.floor( n * Math.random() );
    where the range is [0, n-1]

    Would it be appropriate to correct this in the FAQ
    http://www.jibbering.com/faq/#randomNumber
    and maybe add a short math explanation note based on the sci.math post
    so not leaving reader to wonder why the hey floor() and what's wrong
    with round() ?
    VK, May 1, 2010
    #9
  10. Re: Math.random() and Math.round(Math.random()) and Math.floor(Math.random()*2)

    On Sat, 1 May 2010 at 02:49:07, in comp.lang.javascript, VK wrote:
    >On May 1, 1:30 pm, Ry Nohryb <> wrote:


    <snip>
    >From the Math.round and Math.floor methods
    >descriptions:
    >
    > https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects
    >/Math/Round
    > Returns the value of a number rounded to the nearest integer.
    >
    > https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects
    >/Math/Floor
    > Returns the largest integer less than or equal to a number.
    >
    >I am failing to grasp the exact difference between of them.

    <snip>

    In case anyone has been confused by VK here are some facts.

    round 0.9 is 1.0

    floor 0.9 is 0.0


    John
    --
    John Harris
    John G Harris, May 1, 2010
    #10
  11. Re: Math.random() and Math.round(Math.random()) and Math.floor(Math.random()*2)

    On Sat, 1 May 2010 at 05:17:38, in comp.lang.javascript, VK wrote:

    <snip>
    > return (Math.random() >= 0.5) ? _this : _that;

    <snip>
    >Would it be appropriate to correct this in the FAQ

    <snip>

    The FAQ is correct already.

    Would beginners benefit from seeing a slightly faster routine for a
    special case ?

    John
    --
    John Harris
    John G Harris, May 1, 2010
    #11
  12. Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    VK <> writes:

    > Assuming one needs to have a function returning false or true on each
    > call in pseudo-random order.and using JavaScript native Math.random()
    > method as the basis of the pseudo-randomness. Say the variants of such
    > function are:
    >
    > getAnswer1() {
    > var n = Math.round(Math.random());
    > return n ? true : false;
    > }
    >
    > getAnswer2() {
    > var n = Math.floor(Math.random()*2);
    > return (n==2) ? true : false;


    As stated elsewhere, this should read
    return (n == 1) ? true : false;
    or, preferably,
    return n == 1;

    > }
    >
    > Leaving obvious practical testing by platforms aside:
    >
    > Is there are theoretical considerations that pseudo-randomness
    > (predictability) of either of above will be better or worse than the
    > other one?


    No, they are (obviously?) exactly identical. They map exactly the same
    results of Math.random() to true and false respectively.
    In both cases, a value in the range [0..0.5[ is mapped to false
    and a value in the range [0.5..1[ is mapped to true.

    > JavaScript Kit site claims that the second bits first:
    > http://www.javascriptkit.com/javatutors/randomnum.shtml
    > but they don't disclose the underlaying reasoning.


    I guess their point is that to generate an integer in the range [0..n[,
    Math.floor(Math.random() * n)
    is better, in general, than
    Math.round(Math.random() * (n - 1))
    .... which is pretty old news (not that people still don't bungle it
    regularly, but it's embarrasing every time it happens).

    The funny thing is that for n = 2, the unevenness of using the Math.round
    doesn't matter, which is the case you are asking about.

    --
    Lasse Reichstein Holst Nielsen
    'Javascript frameworks is a disruptive technology'
    Lasse Reichstein Nielsen, May 1, 2010
    #12
  13. VK

    Evertjan. Guest

    Lasse Reichstein Nielsen wrote on 01 mei 2010 in comp.lang.javascript:

    > As stated elsewhere, this should read
    > return (n == 1) ? true : false;
    > or, preferably,
    > return n == 1;
    >


    or:

    return !n-1;

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., May 1, 2010
    #13
  14. VK

    Ry Nohryb Guest

    Re: Math.random() and Math.round(Math.random()) andMath.floor(Math.random()*2)

    On May 1, 11:20 pm, "Evertjan." <> wrote:
    > Lasse Reichstein Nielsen wrote on 01 mei 2010 in comp.lang.javascript:
    >
    > > As stated elsewhere, this should read
    > >    return (n == 1) ? true : false;
    > > or, preferably,
    > >    return n == 1;

    >
    > or:
    >
    > return !n-1;


    return !n;
    --
    Jorge.
    Ry Nohryb, May 2, 2010
    #14
  15. In comp.lang.javascript message <1b5852ed-217d-4b0a-8952-1212f96c5107@i9
    g2000yqi.googlegroups.com>, Sat, 1 May 2010 00:54:03, VK
    <> posted:
    >Assuming one needs to have a function returning false or true on each
    >call in pseudo-random order.and using JavaScript native Math.random()
    >method as the basis of the pseudo-randomness. Say the variants of such
    >function are:
    >
    >getAnswer1() {
    > var n = Math.round(Math.random());
    > return n ? true : false;
    >}
    >
    >getAnswer2() {
    > var n = Math.floor(Math.random()*2);
    > return (n==2) ? true : false;
    >}


    That one always returns false.


    >Leaving obvious practical testing by platforms aside:
    >
    >Is there are theoretical considerations that pseudo-randomness
    >(predictability) of either of above will be better or worse than the
    >other one? JavaScript Kit site claims that the second bits first:
    > http://www.javascriptkit.com/javatutors/randomnum.shtml
    >but they don't disclose the underlaying reasoning.


    The cited page is basically incorrect; the author is probably rephrasing
    something that he does not understand.


    Only the incompetent, or those writing for them, feel a need to write
    ? true : false or ? false : true.

    The proper answer is not to use Math.random >= 0.5 , but to use
    Math.random < 0.5 - the result should be equally good, but the
    latter takes fewer characters and out to be equally quick.

    Implementations of Math.random should be pretty good at returning the
    same number of results < 0.5 as not < 0.5 - but if there are any based
    on N-bit shift registers with XOR feedback, then there should be with
    those on average in every 2^N-1 results one more in one "half" than in
    the other. That can, in practice, only be tested in JavaScript by
    incipient struldbrugs.

    One could use !Math.round(Math.random()) , but in principle one
    should first check (in all browsers) that Math.round does not do
    Bankers' Rounding. Anti-Bankers would be OK.

    --
    (c) John Stockton, nr London UK. ???@merlyn.demon.co.uk Turnpike v6.05 MIME.
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
    Check boilerplate spelling -- error is a public sign of incompetence.
    Never fully trust an article from a poster who gives no full real name.
    Dr J R Stockton, May 2, 2010
    #15
  16. In comp.lang.javascript message <>, Sat, 1 May
    2010 21:30:44, Lasse Reichstein Nielsen <> posted:

    >As stated elsewhere, this should read
    > return (n == 1) ? true : false;
    >or, preferably,
    > return n == 1;


    Or return ! Math.floor(Math.random()*2);

    That gives the opposite answer, but who cares?

    return Math.random()<0.5 should be quicker.



    >I guess their point is that to generate an integer in the range [0..n[,
    > Math.floor(Math.random() * n)
    >is better, in general, than
    > Math.round(Math.random() * (n - 1))
    >... which is pretty old news (not that people still don't bungle it
    >regularly, but it's embarrasing every time it happens).
    >
    >The funny thing is that for n = 2, the unevenness of using the Math.round
    >doesn't matter, which is the case you are asking about.


    Since using Math.round makes the two end bins each half as probable as
    the rest, n = 1 and n = 1 are the only cases where it gives equi-
    probability.

    However, there is a class of problems where Math.round is good : "a
    metre stick is repeatedly put at random positions within a ten-metre
    tube marked out in one-metre sections - what is the probability
    distribution of which section its centre is in?"
    (for the metrically-challenged : use .replace(/re\b/g, "er") on that)

    --
    (c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 7.
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
    MiniTrue is good for viewing/searching/altering files, at a DOS / CMD prompt;
    free, DOS/Win/UNIX, new via <URL:http://www.merlyn.demon.co.uk/pc-links.htm>.
    Dr J R Stockton, May 2, 2010
    #16
    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. Replies:
    0
    Views:
    1,087
  2. Replies:
    4
    Views:
    494
  3. Replies:
    13
    Views:
    10,652
  4. OliverMarchand

    Float.round - should it be round-to-even

    OliverMarchand, Apr 12, 2006, in forum: Ruby
    Replies:
    2
    Views:
    220
    OliverMarchand
    Apr 12, 2006
  5. cerr

    reading file round and round

    cerr, Mar 19, 2010, in forum: Perl Misc
    Replies:
    6
    Views:
    178
    Peter J. Holzer
    Mar 20, 2010
Loading...

Share This Page