0

This is the part of the code in my "ProjectEntity" class (where I make SQL calls with hibernate)

@Column(name = "BUDGET")
private float budget;

public float getBudget() {
return budget;
}

public float setBudget(float budget) {
this.budget = budget;
}

From another class I call my setter like this:

newProject.setBudget(Float.parseFloat(strTotalAmount.substring(0, strTotalAmount.indexOf(" (hrs)"))) * m);

In here I have a String called strTotalAmount and it looks like this: "51.0 (hrs)". So it basically gets the value 51.0 from string and multiplies with float "m" which is equal to 47.6 Everything is fine till here. It should have set the value to 2427.6 Instead it sets to 2427.5999. What might be the problem?

Note: At first in ProjectEntity "budget" value was double instead of float. I've changed it into float. But nothing has changed.

brainmassage
  • 1,114
  • 2
  • 21
  • 41

2 Answers2

1

Floats are approximations in Java if you need exact numbers, especially when working with money use BigDecimal.

public class FloatTest {
    public static void main(String[] args) {
        BigDecimal f1 = new BigDecimal("51.0");
        BigDecimal f2 = new BigDecimal("47.6");

        System.out.println(f1.multiply(f2));
    }
}
Kevin Bowersox
  • 88,138
  • 17
  • 142
  • 176
1

If you want accurate floating point computations then use the BigDecimal class instead of float or double.

A BigDecimal is an exact way of representing numbers. A Double has a certain precision. Working with doubles of various magnitudes (say d1=1000.0 and d2=0.001) could result in the 0.001 being dropped alltogether when summing as the difference in magnitude is so large. With BigDecimal this would not happen.

The BigDecimal class gives its user complete control over rounding behavior, forcing the user to explicitly specify a rounding behavior for operations capable of discarding precision (divide and setScale). Eight rounding modes are provided for this purpose.

Two types of operations are provided for manipulating the scale of a BigDecimal: scaling/rounding operations and decimal point motion operations.

Scaling/Rounding operations (SetScale) return a BigDecimal whose value is approximately (or exactly) equal to that of the operand, but whose scale is the specified value; that is, they increase or decrease the precision of the number with minimal effect on its value.

Decimal point motion operations (movePointLeft and movePointRight) return a BigDecimal created from the operand by moving the decimal point a specified distance in the specified direction; that is, they change a number's value without affecting its precision.

Ankur Lathi
  • 7,215
  • 4
  • 34
  • 45