I notice some issues with the Java float precision
Float.parseFloat(\"0.0065\") - 0.001 // 0.0055000000134110451
new Float(\"0.027\") - 0.001
I would convert your float to a string and then use BigDecimal.
This link explains it well
new BigDecimal(String.valueOf(yourDoubleValue));
Dont use the BigDecimal double constructor though as you will still get errors
See What Every Computer Scientist Should Know About Floating-Point Arithmetic. Your results look correct to me.
If you don't like how floating-point numbers work, try something like BigDecimal instead.
The problem is simply that float
has finite precision; it cannot represent 0.0065
exactly. (The same is true of double
, of course: it has greater precision, but still finite.)
A further problem, which makes the above problem more obvious, is that 0.001
is a double
rather than a float
, so your float
is getting promoted to a double
to perform the subtraction, and of course at that point the system has no way to recover the missing precision that a double
could have represented to begin with. To address that, you would write:
float f = Float.parseFloat("0.0065") - 0.001f;
using 0.001f
instead of 0.001
.
From the Java Tutorials page on Primitive Data Types:
A floating-point literal is of type float if it ends with the letter
F
orf
; otherwise its type is double and it can optionally end with the letterD
ord
.
So I think your literals (0.001
) are doubles and you're subtracting doubles from floats.
Try this instead:
System.out.println((0.0065F - 0.001D)); // 0.005500000134110451
System.out.println((0.0065F - 0.001F)); // 0.0055
... and you'll get:
0.005500000134110451
0.0055
So add F
suffixes to your literals and you should get better results:
Float.parseFloat("0.0065") - 0.001F
new Float("0.027") - 0.001F
Float.valueOf("0.074") - 0.001F
Floating point cannot accurately represent decimal numbers. If you need an accurate representation of a number in Java, you should use the java.math.BigDecimal class:
BigDecimal d = new BigDecimal("0.0065");
You're getting the right results. There is no such float
as 0.027 exactly, nor is there such a double
. You will always get these errors if you use float
or double
.
float
and double
are stored as binary fractions: something like 1/2 + 1/4 + 1/16... You can't get all decimal values to be stored exactly as finite-precision binary fractions. It's just not mathematically possible.
The only alternative is to use BigDecimal
, which you can use to get exact decimal values.