Mathematical operations in Java: java.util.Math (ctd)

This page continues from the previous page on information and performance of methods provided by the java.util.Math class. Please see that page in particular for information about interpreting the timing information given below.

Math.log(): natural logarithm

The method Math.log() computes the natural logarithm, or in other words, the opposite of Math.exp(), and often written either ln(x) or log10(x). Like ex, calculating natural logarithms crops up in various mathematical applications.

Hotspot on Intel architectures makes use of the FYL2X instruction which calculates a base 2 logarithm, and the equivalence ln(x) ≡ log2 * log2(x). With this implementation, calling Math.log() appears to take in the order of 50 clock cycles on our test i7 machine, or about 25-50 times slower than a floating point addition depending on circumstances.

Math.pow(): calculating arbitrary powers

The Math.pow() method can be used to calculate arbitrary powers. Specifically, calling Math.pow(x, y) calculates xy, where both x and y can be any arbitrary double and the result will be the nearest double representation possible to the actual answer.

It should be noted that Math.pow() is potentially very slow compared to many other operations. On our test system, it takes something in the order of 600 clock cycles in the worst case. However, the algorithm used does provide for a a special "fast case" where y is a power of 2 where it takes in the order of 30 clock cycles.

Math.sin(), Math.cos() and Math.tan(): calculating sines, cosines and tangents

These functions calculate the key trigonometric functions sine, cosine and tangent which define the relationship between the angle of a right-angled triangle and the ratios of the lengths pairs of its sides. These functions crop up in a variety of applications, from the simple drawing of geometrical shapes to more complex operations such as the analysis of waveforms. They each take their input value in radians, where a full circle or 360 degrees is equivalent to 2*pi radians. (In a program, you can get the double value of PI using the constant Math.PI.)

The sine, cosine and tangent functions are all repeating functions, whereby the "core" behaviour of the function with input values between 0 and pi/2 is effectively repeated (with sign changes) over other ranges of input values. Because less "juggling" is required to accommodate this repetition, Java's sin(), cos() and tan() functions have "fast cases" for input values between -pi/2 and pi/2. Approximate number of clock cycles (i.e. relative to the "best case" for a floating point addition on many processors) are approximately as follows:

FunctionInput rangeTiming
(reative to floating point addition)
-pi/2 - pi/2~ 65
< -pi/2 or > pi/2~ 120
Math.tan()-pi/2 - pi/2~ 80
< -pi/2 or > pi/2~ 200

Notice that tan() is functionally equivalent to sin()/cos() but that it is faster (and marginally more accurate) to use the tan() function because a different method of calculation is actually used.

If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.

Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.