dimo414
dimo414

Reputation: 48884

Java Math.cos() Method Does Not Return 0 When Expected

Using Java on a Windows 7 PC (not sure if that matters) and calling Math.cos() on values that should return 0 (like pi/2) instead returns small values, but small values that, unless I'm misunderstanding, are much greater than 1 ulp off from zero.

Math.cos(Math.PI/2) = 6.123233995736766E-17
Math.ulp(Math.cos(Math.PI/2)) = 1.232595164407831E-32

Is this in fact within 1 ulp and I'm simply confused? And would this be an acceptable wrapper method to resolve this minor inaccuracy?

public static double cos(double a){
    double temp = Math.abs(a % Math.PI);
    if(temp == Math.PI/2)
        return 0;
    return Math.cos(a);
}

Upvotes: 9

Views: 6302

Answers (3)

Goibniu
Goibniu

Reputation: 2231

This is a common error when you are starting out, this link has a very technical discussion of the reasons why. http://docs.sun.com/source/806-3568/ncg_goldberg.html

But in it's simplest form, in the same way that we can't exactly represent 1/3 in the decimal system, there are values that can't be represented exactly in the binary system

Upvotes: 2

Slartibartfast
Slartibartfast

Reputation: 8805

You should never use == with doubles. You must always do within en error margin. 10-17 is good precision if you ask me. Ulp figure of 10-32 is just precisson of double that is in 10-17 order of magnitude, as 2.220446049250313E-16 is the precision of the number in 100 magnitude.

Upvotes: 7

Jon Skeet
Jon Skeet

Reputation: 1504022

Don't forget that Math.PI/2 is an approximation. It's not going to be exactly pi/2, so the result of cos(Math.PI/2) isn't going to be exactly 0. Math.cos may be returning a pretty accurate version of the cosine of the exact value returned by calculating Math.PI/2.

Upvotes: 11

Related Questions