Java has two built-in floating point data types: float and double. Essentially, these represent and allow calculations on real numbers (i.e. whole numbers or otherwise) with a range and precision that are suitable for most everyday calculations:
Data type | Bytes used | Significant figures (decimal) | Range |
---|---|---|---|
float | 4 | 7 | approx 38 places before or after the decimal point |
double | 8 | 15 | approx 300 places before or after the decimal point |
In most cases, this boils down to the following:
So in our program, we may then perform basic calculations as follows— essentially "as you'd expect":
double a = 7.45; double b = 1.52; double sum = a + b; double multiplied = a * b;
The four basic operators +, -, * and / essentially do "what you'd expect".
If you're used to programming in BASIC, you may be used to using the hat operator (^) to comput powers. In Java, as in various languages, the ^ operator actually performs an Exclusive OR (XOR). To compute a power in Java, there are two main options. Firstly, if easily possible, replace the power by a multimplication: for example, to square a number, multiply itself by itself; to cube a number, multiply itself by itself twice etc:
double xSquared = x * x; double xCubed = xSquared * x; double xQuadrupled = xSquared * xSquared;
Where this isn't possible or feasible (e.g. the power is large or not a whole number), then use the Math.pow() method from the java.util.Math class. For example, to calculate 401.5 and x2y:
double result = Math.pow(40, 1.5); double result2 = Math.pow(x, 2*y);
The Math.pow() method is typically around 300-600 times slower than a mutliplication, but in many applications this doesn't matter: the computation still takes a tiny fraction of a millisecond.
Like Math.pow(), the java.util.Math class contains various other static methods for performing common operations such as trigonometric functions and calculating logarithms.
You may be wondering what I have against the poor float type and why I recommend always using double rather than float. Well essentially because:
The float type offers poor precision and I would posit that the motivation for using it is largely historic, stemming from a time when memory was much more scarce and processor operations were genuinely faster on 4-byte numbers compared to 8-byte numbers. These days, even if you have to store millions of numbers in memory, you may as well double your memory capacity for a few dollars rather than halving the storage space of each number. And, with the exception of division, processor calculation units are so fast that, either on floats or doubles, the actual speed of the operation is determined by the length of a clock cycle rather than the number of digits1.
On the next page, we give an overview of the java.util.Math class, which provides methods for performing various common mathematical operations.
Or put more simply: the calculation unit of the processor can manipulate an 8-byte number faster than the result can be processed, so that there is no overall saving in using a 4-byte number.
If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants. Follow @BitterCoffey
Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.