Horcrux7
Horcrux7

Reputation: 24477

How to round a float value to double value?

The follow code round incorrectly for a human people:

double d = 0.7F;
System.out.println( d );

print the value: 0.699999988079071

The follow code work better:

double d = Double.valueOf( Float.toString( 0.7F ));
System.out.println( d );

But create an additional String. Are there a more performance conversion of float to double without an extra string?

The code line are simple and demonstrate only the problem. The program is more complex. The float values are in a one part of a complex model. The formatting layer use only double. Also DecimalFormat accept only double and not float.

Upvotes: 0

Views: 1801

Answers (5)

Louis Wasserman
Louis Wasserman

Reputation: 198471

double d = 0.7F;
System.out.println( d );

print the value: 0.699999988079071

The conversion is correct.

When you print out a float f, it prints out enough digits so that the value it prints out is closer to the true value of f than any other float.

When you print out a double, it prints out enough digits so that the value it prints out is closer to the true value of d then any other double.

The conversion from float to double is exact, it's just showing you a value closer to the true value you'd had in your float. Double.valueOf( Float.toString( 0.7F )) is not more accurate; it just pretends your values are nicer than they actually are.

Upvotes: 2

wgitscht
wgitscht

Reputation: 2776

if it's all about the output (for humans) i would suggest to use printf:

System.out.printf("Value: %.2f", d);

doing the conversion with FloatingDecimal is surely faster, and prints 0.7 as well

  Double doubleResult = new FloatingDecimal(0.7F).doubleValue();

Upvotes: 2

RealSkeptic
RealSkeptic

Reputation: 34648

Yes, use

double d = 0.7D;

Using F means it's a float constant, and then it's promoted to double and may not be the closest number to 0.7 that can be represented with a double precision floating point, as the mantissa is not extended in any way.

0.7D is a double constant to begin with.

Upvotes: 5

Peter Lawrey
Peter Lawrey

Reputation: 533870

If you know what precision you want you can round it to say 6 decimal places. eg.

public static double round6(double x) {
    return Math.round(x * 1e6) / 1e6;
}

round6(0.7f) == 0.7

The fact the x passed in was a float doesn't matter provided this precision is suitable.

Upvotes: 2

Pascal Cuoq
Pascal Cuoq

Reputation: 80355

But create an additional String. Are there a more performance conversion of float to double without an extra string?

Allocating a short-lived block of a few bytes is only the tip of the iceberg. The “conversion” that you desire fundamentally requires going from binary floating-point to decimal representation and then back to binary floating-point, and these conversions aren't cheap regardless of how the intermediate decimal representation is stored.

If you know that the float values you are concerned with come from decimal values with two digits after the dot, you could use:

double d = Math.round(f * 100.0) / 100.0;

This incurs only one division plus Math.round which is cheaper than one conversion to or from decimal. And any decent compiler should produce code for it that does not allocate.

Upvotes: 2

Related Questions