0

I'm using a float constant and setting a objects private float variable to the float constant below, but when the object outputs the value it was set to, it's rounding up the last digit in the float.

private final float RF_FREQUENCY = 956.35625f;
Object o = new Object();
o.setRFFrequency(RF_FREQUENCY);
System.out.println(o.getRFFrequency);

Output: 956.35626

The variable in the object is declared as protected float rfFrequency; and below are the getters and setters.

public float getRFFrequency() {
        return rfFrequency;
    }
public void setRFFrequency(float value) {
        this.rfFrequency = value;
    }

Any idea why this is happening?

5
  • 1
    possible duplicate of Help with float numbers in Java Commented Feb 17, 2012 at 14:11
  • 1
    It's at least the second time this question is asked just today Commented Feb 17, 2012 at 14:12
  • it will be better to change the float to BigDecimal, based in the post from @JBNizet Commented Feb 17, 2012 at 14:14
  • Use this online calculator to find the answer for yourself. Commented Feb 17, 2012 at 14:15
  • @JBNizet Sorry, I did a search but didn't see anything quite like the question I was asking. Thanks for the link though. Commented Feb 17, 2012 at 14:17

3 Answers 3

3

Because single precision IEEE754 floating point numbers only have 23 bits of precision (24 including the implicit 1 bit at the start).

That equates to roughly seven decimal digits and you can see that your number has eight digits in it.

All that's happening is that the computer is choosing the closest number to what you asked for that it can represent.

If you need more precision, use a double. That gives you 52/53 bits which equates to about 15 decimal digits.

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

5 Comments

So how would one go about still using a float and outputting the intended value - 956.25625?
One wouldn't with a float but, if by "float" you meant general floating point rather than specific type, one could use a double.
@TyC final float RF_FREQUENCY = 956.35625f; System.out.println(String.format("%.5f", RF_FREQUENCY));
...That is to say, @TyC, that you really can't. You can't store 956.25625 in a float without getting it rounded to the nearest binary fraction with 23 bits of precision.
You simply can't put 26 bits into 23. Until it is float, not rar archive.
2

Floats can't represent every number, so numbers are rounded. Doubles are the same, but with a higher precision. If you use Double your output will be 956.35625 (in this special case).

Comments

1

After some testing, I got this result:

final float RF_FREQUENCY = 956.35625f;
System.out.println(String.format("%.5f", RF_FREQUENCY));
final BigDecimal xRF_FREQUENCY = new BigDecimal(956.35625);
System.out.println(String.format("%.5f", xRF_FREQUENCY));

And the output was:

956,35626
956,35625

So, as its explained in more details from coderanch and in this blog post, I recommend you to change to BigDecimal.

EDIT: I've found another post about same problem in stackoverflow Double vs. BigDecimal? Hope it helps you.

1 Comment

I would use BigDecimal only if a double doesn't provide the required precision (for example cryptographic algorithms). I haven't tested, but I'm sure computations on BigDecimal are more expensive than computations on double (especially on 64bit machines).

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.