3

Today I have just discovered the oddest bug that I have ever seen, which took me several hours to find. I've narrowed down the problem to a single line of code which simply is:

double cosAngle = Math.cos(angleInRadians);

For certain angles (or periods of time?) the function returns the wrong answer!

I'm certain that it's not due to incorrect conversion of degrees to radians or other common mistakes that people make with the cos function.

It only happens to my Nexus 4 device running 4.4.2 and I ran a little test from the main thread:

Log.d("test", "---------------- Beginning Test ---------------------- ");
for(int i = 0; i < 1000; i++) {
    Log.d("test", "Math.cos(1.603635633038609d):\n" + Math.cos(1.603635633038609d));
}

When I print the solution to logcat I get:

D/test    ( 7875): Math.cos(1.603635633038609d):
D/test    ( 7875): -0.03283340413433994
D/test    ( 7875): Math.cos(1.603635633038609d):
D/test    ( 7875): -0.04844533640025519

And it randomly fluctuates between these two values. The correct answer being -0.0328.. Has anyone any insight as to what might be happening? Is this a software/hardware issue?

It has visual implications as it causes pixels to flicker and other weird effects.

Luke Deighton
  • 328
  • 2
  • 10
  • This does not occur on standard java. Tested on OpenJDK7 with ten million iterations: no variance. – daveloyall May 23 '14 at 18:44
  • I'm aware that this could entirely be a problem with my phone and not due to java/android. I couldn't reproduce the problem on any other device or version of Android. I find it completely bewildering. Can a hardware defect cause this? – Luke Deighton May 23 '14 at 18:51
  • 1
    Bewildering indeed. I'm having trouble imagining an ordinary hardware problem (bad ram, bad CPU, bad bus) that wouldn't also cause the phone to crash randomly and/or cause more wildly varying numeric results in your test... Based the method described here: http://stackoverflow.com/questions/6359847/convert-double-to-binary-representation I've determined that the wrong answer is off by 22 bits (of 64 in the double), which is meaningless of course, for multiple reasons. A purely logical answer to your question: can a hardware defect cause this? is "Sure!". :) – daveloyall May 23 '14 at 20:40
  • Most curious. I could not reproduce this behavior with my Nexus 4 either. – matiash May 23 '14 at 22:19
  • You could try adding the `strictfp` keyword to the method (e.g. `private strictfp void method()` – MusicMaster Aug 21 '14 at 21:16

0 Answers0