Mathematical operations in Java: java.util.Math

Beyond the basic floating point arithmetic operations, the java.util.Math class provides various static methods to perform other common trigonometric and arithmetic operations on floating point numbers. In general, these methods operate on doubles and perform said operations to within the precision allowed by a double.

Depending on your VM and architecture, the methods of the Math class may either be implemented in software or, where available, be compiled directly to corresponding machine code instructions. The Hotspot software implementations are based on Sun's freeware fdlibm library. In the descriptions below, I include some empirical information on the performance of the various methods, and indicate cases that are compiled directly to an underlying machine instruction. It is important to remember that both the software and hardware implementations aim to produce an approximation which is indistinguishable from the theoretical "actual" result within the precision of a double". Thus, depending on the input parameters, they typically go through different code paths to produce their result, and hence actual performance of the java.util.Math methods can vary depending on those input values.

Note about instruction timings

The timing indications I give below are mostly based on empirical test timings made on an Intel i7 machine and from the assembler output of 64-bit Hotspot fastdebug build 1.7.0-ea-b126. It should be noted that low-level timings are a complex issue on modern architecture, because the timing of a particular instruction often depends on its dependency on surrounding instructions. But as a rough guide, addition with register operands (and indeed some other instructions such as multiplication) can "burst" at one instruction per clock cycle when not dependent on adjacent instructions, but in other situations will take up to 2 clock cycles on average. On older Intel architecture, typical "worst case" timings of floating point arithmetic instructions are reported to rise to 5-6 clock cycles. For more data and information on the issue of instruction timings, see the Intel 64 and IA-32 Architectures Optimization Reference Manual as well as Granlund, Instruction latencies and throughput for AMD and Intel x86 processors.

Calculating the square root: Math.sqrt()

The Java method Math.sqrt() calculates the square root of its single argument, returning the result to the precision of a double. On many platforms, a machine code instruction is actually available to perform square roots, and in such cases a good VM will replace a call to Math.sqrt() with the equivalent machine code instruction so that no actual method call is made. Hotspot on Intel platforms, for example, JIT-compiles Math.sqrt() to a SQRTSD instruction. The result is that Math.sqrt() appears to take around 20 clock cycles, or 10-20 times as long as a floating point addition.

Maths geeks will note that this method strictly returns the positive real root. So for example, Math.sqrt(4) will return 2, but strictly speaking, -2 is also a square root of 4.

Math.exp(): calculating ex

The Math.exp() method calculates e ("Euler's number") to the power x, its single argument. This calculation has a variety of applications, and various other mathematical functions, such as the calculation of the arbitrary power xy, can be derived from it.

The precise time taken by Math.exp() is a slightly complex matter, because how much effort is required for a calculation accurate to within the limitations of a double depend on the range of the input value. But typically, the calculation will be in the order of 100 clock cycles, or 50-100 times slower than a floating point addition depending on the circumstance.

For more information, see the separate page on the performance of Math.exp() and possible approximations which for some applications can speed up the calculation considerably.

Next: trigonometric and other methods

On the next page, we continue to look at trigonometric and other methods of the java.util.Math class.

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.