1

I created a jQuery plugin but I have a problem, I use the following code:

Math.floor(Math.random()*500)

I add the result to a element, but bizarrely the result is every time the same.

If I add a alert() to the line after the random-number-generation, I get random values, why? I want to get without the alert() random integers. But how?

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
user237060
  • 2,599
  • 4
  • 18
  • 7
  • 2
    I’m trying your code in Firebug’s JavaScript console, and I’m getting a different number every time. What browser are you using? Could you post the complete code? (i.e. including adding the result to an element). – Paul D. Waite Dec 29 '09 at 02:04
  • 2
    At the very least, what *is* the result you get every time? – Matchu Dec 29 '09 at 02:06
  • 10
    Could you post the code of your plugin?, It sounds to me like a *closure problem*... – Christian C. Salvadó Dec 29 '09 at 02:06
  • 2
    I have seen this occur when called in very tight loops, for some reason it gets optimized to always return the same value instead of re-executing the call. Its been a long time since I saw it though. – GrayWizardx Dec 29 '09 at 02:14
  • Test page: http://www.pauldwaite.co.uk/test-pages/1972550/ I get 50 different numbers in Firefox 3.5 and Chrome 4 on OS X. – Paul D. Waite Dec 29 '09 at 02:27
  • Same results (i.e. 50 different numbers) in IE 6, 7 and 8 on XP. – Paul D. Waite Dec 29 '09 at 02:35
  • 2
    Can everyone please pay attention to CMS? He is likely correct. You need to post exactlly *how* you are adding this random number to an element. – Breton Dec 29 '09 at 02:53

4 Answers4

2

The random number function is an equation that simulates being random, but, it is still a function. If you give it the same seed the first answer will be the same.

You could try changing the seed, and do this when the javascript is first loaded, so that if there is a time component to the random number generator, then it can use the delays of pages being loaded to randomize the numbers more.

But, you may want to change the seed. You can use the Date() function, then get the milliseconds and use that as the seed, and that may help to scramble it up first.

My thought that there is a time component to the generator is the fact that it changes with an alert, as that will delay when the next number is generated, though I haven't tested this out.

UPDATE:

I realize the specification states that there is no parameter for Math.random, but there is a seed being used.

I came at this from C and then Java, so the fact that there was no error using an argument led me to think it used it, but now I see that that was incorrect.

If you really need a seed, your best bet is to write a random number generator, and then Knuth books are the best starting point for that.

EmptyArsenal
  • 7,314
  • 4
  • 33
  • 56
James Black
  • 41,583
  • 10
  • 86
  • 166
  • 8
    There is no way you can change the seed for Math.random() in Javascript. It seeds it using the current time when the script starts executing. – Matt Greer Dec 29 '09 at 02:39
  • @Matt - I have always just passed in a value, I didn't realize it was being ignored. – James Black Dec 29 '09 at 03:39
-1

This is how I solved it for my needs. In my case it works just fine because I will only be requesting numbers sporadically and never sequentially or in a loop. This won't work if you use it inside a loop since it's time based and the loop will execute the requests just milliseconds apart.

function getRandomNumber(quantity_of_nums){
    var milliseconds = new Date().getMilliseconds();
    return Math.floor(milliseconds * quantity_of_nums / 1000);
}

This will give you a number from 0 to quantity_of_nums - 1

Hope it helps!

Lezka
  • 39
  • 5
  • 1
    `1820,1822,1824,1826,1826,1828,1828,1830,1830,1832` doesn't seem very random. `for (i = 0; i < 10; i++) { console.log(getRandomNumber(2000)) }` – Kevin B Jan 20 '16 at 20:48
  • Kevin B. you are very right, this won't work if you use it inside a loop since it's time based and the loop will execute the requests just milliseconds apart. Changed the text to clarify this aspect. Thanks for the heads up. – Lezka Jan 21 '16 at 10:29
  • This is not random at all, a date is a really predictive number. – Sebi2020 Jan 17 '22 at 12:12
-6

Random number generators are really pseudo random number generators - ie they use a formula to calculate a stream of numbers that is practically random.

So, for the same initial input values (seed) you will get the same stream. So the trick is to seed the random number generator with a good actually random seed.

So you need to pass in a seed into random() somehow - you could use some kind of hashing of the current time, or any other data that you think has some kind of randomness (if you want it to be "securely random" - that is a whole other subject and probably covered somewhere else).

So use something like: Math.random(Date.getMilliseconds()) - might do closer to what you want.

Michael Neale
  • 19,248
  • 19
  • 77
  • 109
  • Hmm, according to the ECMA-262 spec, `Math.random()` doesn't take any parameters. Do you know which browser `Math.random(Date.getMilliseconds())` works in? – Xavi Dec 29 '09 at 02:15
  • @Xavi, you're right, the above code works because the argument passed to `Math.random` is just simply ignored... http://bclary.com/2004/11/07/#a-15.8.2.14 – Christian C. Salvadó Dec 29 '09 at 02:24
  • Tested with a fixed "seed", and both IE and Firefox still returned random values. Xavi is right, the parameter is just ignored. – Badaro Dec 29 '09 at 02:25
  • can `(Math.random() + new Date().getMilliseconds() / 1000) / 2` be considered as 'seeding'? – Lukman Dec 29 '09 at 02:52
  • 3
    you are trying to "add randomness to the result", which is a good-spirited idea, but there is a catch: the distribution of the average of two random numbers is *not* uniform. In layman terms, it means that, in your suggestion, the probability of, say, getting 0.5 is bigger than the probability of getting 0.25. For more technical (mathematical) information, see: http://www.statisticalengineering.com/central_limit_theorem.htm – chesterbr Nov 25 '11 at 17:31
-15

You could use

#include <sys/time.h>

and then to get a range of seeds ranging from 0 to 999,999, use

gettimeofday(&tv, NULL);
srand(tv.tv_usec);

Then, to get the random number in the range 0 - 499, use

r = 500*((double)rand() /((double)(RAND_MAX)+(double)(1.0))));

or add 1 to this result to shift it to the range 1 - 500.

Good luck

John R Doner
  • 2,242
  • 8
  • 30
  • 36
  • 7
    Javascript question, not C/C++. – Badaro Dec 29 '09 at 02:24
  • I certainly would like to know why a down vote was applied to this answer. It is a complete description of a straightforward way to generate the random number range desired, which neither of the previous answers addressed. – John R Doner Dec 29 '09 at 02:27
  • 16
    Because the question asked how to generate a random number in JavaScript (in the context of writing a jQuery plugin), and your answer explained how to generate a random number in C or C++. I don’t think it’s possible to write jQuery plugins in C or C++. Great answer, just not for this question. – Paul D. Waite Dec 29 '09 at 02:32