4 ms·
Why is Math.sin(Math.PI/2) returning an exact value but not Math.sin(Math.PI*2)?
System.out.println(Math.PI); //3.141592653589793
System.out.println(Math.sin(Math.PI));//1.2246467991473532E-16
Yes sin(180d) is 0 and the above value is near to 0.
System.out.println(Math.sin(2 *
Math.PI));//-2.4492935982947064E-16
Yes sin(360d) is 0 and the above value is near to 0.
However,
Math.sin(Math.PI/2) return 1.0
Now, I don't get why this returns 1.0 and why not a number
near to 1 but not exactly 1?
Math.sin(Math.PI/6) returns 0.5
Same question here because Math.PI is not exact, why is its division so exact?
This is in java
- Someone 2y ago> Math.sin(Math.PI/2) return 1.0 > Now, I don't get why this returns 1.0 and why not a number near to 1 but not exactly 1? ‘Accident’ of the implementation. When you feed Math.sin that IEEE float that’s close to π ÷ 2 it returns an approximation of its sine. In this case, the rounded result of 1.0, a result that you seem to think is an exact result. > Same question here because Math.PI is not exact, why is its division so exact? It’s not that computing Math.PI ÷ 6 is exact, but that then computing the sine of that value produces ½, which isn’t “so exact”, as technically, the bit pattern for Math.PI ÷ 6 doesn’t stand for π ÷ 6, and could have been computed in another way. By the way, reading https://github.com/openjdk/jdk/blob/bd4160cea8b6b0fcf0507199ed76a12f5d0aaba9/src/java.base/share/classes/java/lang/Math.java#L39 https://github.com/openjdk/jdk/blob/bd4160cea8b6b0fcf0507199..., these results may vary between Java implementations, possibly even between runs (when a method gets called a lot, it may get optimized more, and start using a different implementation)
- shivajikobardan 2y agoYou the real MVP coz landed me into a goldmine. I was thinking this was due to difference in floating point multiplication and dvision algos.
- deleted 2y ago[deleted]
- WCSTombs 2y agoI'm not a Java expert, but I'm fairly certain this is just a feature of roundoff error and how it propagates through computations, and how floating-point values are represented. sin(pi/2 + x) = cos(x) = 1 - x^2/2 + {lower-order terms} When you compute Math.sin(Math.PI/2), Math.PI/2 is computed as pi/2 (exact) plus a small error term, x, which is on the order of 1e-16 or so. Math.sin(Math.PI/2) is then computed as sin(pi/2 + x), which is about 1 - x^2/2. But since x is on the order of 1e-16, x^2/2 is on the order of 1e-32, and the closest double-precision value to 1 - x^2/2 can easily be seen to be exactly 1.0. On the other hand, sin(2*pi + x) = sin(x) = x + {lower-order terms} When you compute Math.sin(2*Math.PI), 2*Math.PI is computed as 2*pi (exact) plus again a small error term x which is on the order of 1e-16, and Math.sin(2*Math.PI) is very close to that error term x. The closest double-precision value to x is much closer to x than zero is, because x is already very small and the relative approximation error in its best double-precision approximation is on the order of 1e-16. Thus, you get a small but nonzero result that is very close to the original approximation error of 2*Math.PI versus the mathematical 2*pi. To fully follow that argument above, you need to know a few things about numerical computation: - Most (but not all) computational environments implement some version of the IEEE-754 standard, and I'm assuming this is also true of Java. - IEEE-754 requires that all the basic operations, including trigonometric functions, behave as if the exact result was computed and then rounded to the nearest double-precision value. - In IEEE-754, floating point numbers are essentially represented in scientific notation, or more precisely as +/-(1.XXXX...) * 2^E where the 1.XXXX... is a binary number with a fixed number of binary digits after the binary point, and E is an integer represented using a fixed number of bits. (For double-precision, I believe the XXXX... has 52 bits, and E has 11 bits.)
- shivajikobardan 2y agoI want to study more about how an example processor computes various stuffs like sqrt, sin, multiplication, addition, subtraction, division of floating point numbers. I've studied computer organization books and understood the IEEE754 notation about floating point representation, but I still can't do the calculations of division, sqrt by hand(although I can compute the floating point representation in terms of mantiassa, sign and exponent by myself manually). I know this might sound stupid to hand calculate everything, but that's what gives me chills at night.