I input 179.9 in an EditText
. When I retrieve it, the value is different if it's stored as a float
.
final EditText valueInput = mEntryDialogView.getValueInput();
final CharSequence input = valueInput.getText();
final String inputAsString = input.toString().trim();
final float asFloat = Float.valueOf(inputAsString); //179.899994
final double asDouble = Double.valueOf(inputAsString); //179.9
Something fishy is going on here, could anyone explain to me why the float value is not correct? Even so if I convert the double value above to a float, it will be incorrect.
Moreover, is there anything that can be done to retrieve the value as a float in such a manner that it is equivalent to the actual inputted value?
float and double don't allow to store decimal numbers exactly, because floating point numbers are stored in a binary form (mantissa + exponent) and not as a list of decimal digits, and there is no exact match between the two. You will always lose some precision, even if the system will try to round the values on display to compensate for that.
The maximum precision of a Float is approximately between 6 and 9 decimal digits.
If you want to store a decimal value without losing precision, for example amounts of money, either use
BigDecimal
orString
.Amounts of money can also be stored as an integer value representing cents, but make sure you use a
BigDecimal
or someString
operations to do the conversion without losing precision.Perhaps this you can be useful!!
As has told me a partner, java uses the IEEE754 standard that uses a float to 32 bits. Indeed, if we only have 32 bits, the first bit is sign, eight for the exponent, and the other 23 for the mantissa. We have 179 integer part from 179.9 is 10110011 in binary, which already fill 8 bits of the mantissa, when we calculate the 0.9 decimal in binary multiplying by two and extracting integer part, the first 15 bits are 11100110011, which are those that fit in the mantissa for a float (32 bits). If now recalculated to decimal, the exponent of 2 positive, 0 or negative, these 15 bits of the decimal part becomes 0.82958984325, far from 0.9.
Regards from Tarragona(Spain) :-)
You understand why there are these precision errors using floats or even doubles. If you don't care much about very fast performance, use BigDecimals instead of floats or doubles:
http://developer.android.com/intl/es/reference/java/math/BigDecimal.html