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.