I've looked at some other questions, but they all have disjointed and confusing answers.
I want to have a random 6 digits, which most of the time this scripts work - it does however also produce 7 digit numbers about 20% of the time.
Math.floor((Math.random() * 999999) + 100000)
My questions:
- Why?
- Correct way of avoiding this?
Please don't suggest using substring or something similar as it is a bit of a hack
I've looked at some other questions, but they all have disjointed and confusing answers.
I want to have a random 6 digits, which most of the time this scripts work - it does however also produce 7 digit numbers about 20% of the time.
Math.floor((Math.random() * 999999) + 100000)
My questions:
- Why?
- Correct way of avoiding this?
Please don't suggest using substring or something similar as it is a bit of a hack
Share Improve this question edited May 23, 2017 at 12:05 CommunityBot 11 silver badge asked Aug 4, 2014 at 15:21 tim.bakertim.baker 3,3076 gold badges29 silver badges54 bronze badges 4- It should only do it 1/10th of the time – Alnitak Commented Aug 4, 2014 at 15:25
-
1
It may be helpful to write a generic
randInt
method, and use that rather than inline arithmetic. You can find an example implementation here. – Kevin Commented Aug 4, 2014 at 15:27 - @Alnitak As with all good things, I'm currently thinking my 20% is a little to generous, more like 40% in the last run I did :/ – tim.baker Commented Aug 4, 2014 at 15:31
- @tim.baker it really should only be 10% (assuming correct random distribution). The random part of your range is 0..999,998 instead of 0..899,999 and so it's only when you hit the bit that exceeds 900,000 (which should be 10% of samples) that you end up with seven digits. – Alnitak Commented Aug 4, 2014 at 15:38
2 Answers
Reset to default 7This is a simple calculation range error. NB: text below uses [
and ]
to represent an inclusive range and (
or )
to represent an exclusive range.
To get the range [100000, 999999] which in integer math is equivalent to [100000, 1000000) you need to get a number in the range [0, 900000) and then add 100000, e.g.
Math.floor(900000 * Math.random()) + 100000
The factor is 900000 rather than 899999 because the Math.random()
function produces numbers in the range [0, 1), i.e. not including 1 itself.
well the problem is in your math.
Math.random
produces a float from 0.0 to 1.0 . In the worst case you multiply 1.0 with 999999 and add another 100000 . this results in 1099999.0 (for the biggest case).
this line should always produce a 6-digit number
Math.floor((Math.random() * 899999) + 100000)