3

When I am doing this

value = Float.parseFloat("5555998.558f");

System.out.println("Value: " + value);

It gives me result 5555998.5 rather than 5555998.558 I am using the variable value for some calculation. And I need the exact value i.e. 5555998.558

How to overcome this?

4
  • 3
    Why are you using a float rather than a double? Commented Oct 3, 2014 at 16:32
  • 1
    Why are you using a primitive floating-point data type instead of BigDecimal? Commented Oct 3, 2014 at 16:32
  • the value is coming form a textfield thats why I am doing this. Commented Oct 3, 2014 at 16:33
  • 2
    @user3203455: "the value is coming from a textfield" doesn't explain why you're using float instead of either double or BigDecimal. Commented Oct 3, 2014 at 16:34

4 Answers 4

8

The float value at that high value has a precision of only 0.5, so Java parsed it to the closest float value it could = 5555998.5, and that's what was printed.

To see the difference between the 2 closest values at that magnitude, use Math.ulp (unit in the last place):

String s = "5555998.558f";
float value = Float.parseFloat(s);
System.out.println(value);
System.out.println(Math.ulp(value));

This prints

5555998.5
0.5

You can use a double which has much better precision:

double d = Double.parseDouble(s);
System.out.println(d);
System.out.println(Math.ulp(d));

This prints

5555998.558
9.313225746154785E-10

Interestingly, Double.parseDouble doesn't seem to mind the f on the end. Double.parseDouble converts the String into a double "as performed by the valueOf method of class Double". And Double.valueOf states:

FloatValue:

  • Signopt NaN

  • Signopt Infinity

  • Signopt FloatingPointLiteral

  • Signopt HexFloatingPointLiteral

  • SignedInteger

This method will take a String as if it were a Java numeric literal, which Java supports with a f on the end to indicate a floating-point literal.

Sign up to request clarification or add additional context in comments.

3 Comments

... or better, BigDecimal which will preserve the exact decimal value entered.
@JonSkeet Sure, BigDecimal will have the arbitrary precision. But new BigDecimal("5555998.558f") throws a NumberFormatException because the f is present. Now I'm curious as to why Float.parseFloat and Double.parseDouble seem to ignore the f in the string.
I'm surprised at that too, although it's documented in Float.valueOf. I guess the best solution will depend on why the f is there at all, and what the OP really wants to achieve.
5

BigDecimal is probably your best bet for exact decimal representations.

BigDecimal value = new BigDecimal("5555998.558");

It's immutable, so every operation you do to it will result in you creating a new BigDecimal instance, but its precision is also likely what you need.

Comments

0

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html float: The float data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. As with the recommendations for byte and short, use a float (instead of double) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead. Numbers and Strings covers BigDecimal and other useful classes provided by the Java platform.

So use BigDecimal and you'll have no problem.

Comments

0

you can also do like this :

Double value = Double.valueOf("5555998.558f");
System.out.println("Value: " + value);

output :

Value: 5555998.558

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.