See the previous HN discussion: http://news.ycombinator.com/item?id=960886
A common bug in published code
71–79 of 79 posts
Re: A common bug in published code
#72Re: A common bug in published code
#73One would hope at some point a tool would warn you about this since clearly it could optimize (int) Math.random() to just 0. [queue debate about tools that hold your hands vs understanding what you are actually writing] I wonder if they did the search for if (x = y) bug pre-gcc-4.x-warn what sort of numbers they would get.
"queue debate about tools that hold your hands vs understanding what you are actually writing" For a start, explain why, in Java, (int) Math.random() is a bug. A programmer that happens upon this thread, now knows "this is bad", but has no clue why. A tool will only make the programmer even more reliant on tools and IDEs, so this kind of bug will be eliminated, but the frame of mind that spawned it will live on.
"A random value from 0 to 1 is being coerced to the integer value 0. You probably want to multiple the random value by something else before coercing it to an integer, or use the Random.nextInt(n) method."
That's about as good an explanation as you'd get from anyone.
The way I see it is this. Simple bugs like this happen because _human beings are flawed._ All it takes is a momentary lapse of concentration and you've put the cast in the wrong place in a method you don't write a test for because you're in a hurry, and all it's doing is generating a random number with a standard API so why bother? (Or it's something you wouldn't normally even test for, like assuming something is re-entrant when it isn't)
We're inevitably going to make a certain number of mistakes a day, and it's our duty to put systems into place that catch those mistakes before they cause any more damage than they should.
Re: A common bug in published code
#74Someone should write a tool that scrapes these results and automatically files bugs at the associated bug trackers for open-source projects.
* NPM packages whose package.json file is missing a link to the package's GitHub repo
* Markdown READMEs without the right file extension (for GitHub)
Re: A common bug in published code
#75Earlier quoted context omitted.
Third error: This is not the correct way to randomly pick a number in a set range. The proper way is actually quite complicated. Imagine you do (int) (Math.random() * 10), this could give you numbers from 0 to 10. However, you only get 0 if Math.random() * 10 is less than 0.5, but you get 1 if the value is between 0.5 and 1.5. You are half as likely to see a zero! I can't speak for Python, but in Java it's quite simp…
> I can't speak for Python, but in Java it's quite simple to do it right http://docs.python.org/library/random.html#random.randint
random.randint(a, b) returns a uniformly distributed int value between a (inclusive) and b (inclusive).
Re: A common bug in published code
#76Re: A common bug in published code
#77Earlier quoted context omitted.
Third error: This is not the correct way to randomly pick a number in a set range. The proper way is actually quite complicated. Imagine you do (int) (Math.random() * 10), this could give you numbers from 0 to 10. However, you only get 0 if Math.random() * 10 is less than 0.5, but you get 1 if the value is between 0.5 and 1.5. You are half as likely to see a zero! I can't speak for Python, but in Java it's quite simp…
public class example { public static void main(String[] JAVA_LOL) throws Throwable { // prints "6" System.out.println((int)6.99999); } }
Re: A common bug in published code
#78Earlier quoted context omitted.
A lot of the results I'm seeing in the search have more problems with order of operations -- so long as you multiply the random() result by a good-sized constant before you cast to int, it actually does what it's "supposed" to do.
This is the point of the post. There are no examples that aren't casting Math.random() to an int before doing anything with it thus using a pretty expensive way to represent 0.
Re: A common bug in published code
#79The first few examples are fine. It's the unscaled ones later on, like "longarr[i] = (int) Math.random();" and especially "[Math.abs((int) Math.random()) % 3];" where the authors didn't notice that random() "returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0." Here's another extreme example: (int) Math.random() / Integer.MAX_VALUE % (maxScoreCount + 1); I eyeballed that about…
Have a look at the precedence table for Java: http://introcs.cs.princeton.edu/11precedence/ The cast has higher precedence than multiplication, so the scaling doesn't help at all, unless you use parenthesis to force the right order of evaluation.