Live data from Hacker News

A common bug in published code

google.com

71–79 of 79 posts

Re: A common bug in published code

#72
post #71
post #18

See the previous HN discussion: http://news.ycombinator.com/item?id=960886

Oh, so it always rounds down to zero, that's pretty bad. Casting it to a double would help right?

Instead of

int runs = (int) Math.random() * 1000000;

You'd do

int runs = (int) (Math.random() * 1000000);

Re: A common bug in published code

#73
post #63

One 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.

Findbugs, the popular Java tool I linked to in another comment, explains the bug like this:

"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

#74
post #13

Someone should write a tool that scrapes these results and automatically files bugs at the associated bug trackers for open-source projects.

I've been wanting to do that for:

* 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

#75
post #34

Earlier 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

Actually the python equivalent of "Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive)" would be random.randrange(0, n, 1)

random.randint(a, b) returns a uniformly distributed int value between a (inclusive) and b (inclusive).

Re: A common bug in published code

#76
post #71
post #18

See the previous HN discussion: http://news.ycombinator.com/item?id=960886

Oh, so it always rounds down to zero, that's pretty bad. Casting it to a double would help right?

That would be pointless, because Math.round already returns a double.

Re: A common bug in published code

#77
post #34

Earlier 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); } }

You (and everyone else) are of course right. I remembered the wrong thing, what I said doesn't apply to that method in Java. What does apply is that there are lots of subtleties in generating random numbers, and there's rarely a reason to re-invent the wheel. There's a good example of how subtle pseudorandomness is in the Java documentation, so I will link that instead of embarrassing myself further: http://download.oracle.com/javase/1.4.2/docs/api/java/util/R...

Re: A common bug in published code

#78

Earlier 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.

The comment I was replying to was simply saying that casting the return value of Math.random() will be 0. Which is true, but is not the issue -- order of operations (for people who think the multiplication happens before the cast) is the issue.

Re: A common bug in published code

#79
post #10
post #3

The 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.

Oh, wow! I didn't know that about Java. I see then why I got all the downvotes.
Post reply on HN