0

There is a BigDecimal datatype in java. When I declare the number 5190000000 as BigDecimal like this:

BigDecimal a = new BigDecimal(5190000000L * 1.0F);

, it is excited and the following output is seen:

Output:
5190000128

while I ommit the F as float value, it is correct like this:

BigDecimal a = new BigDecimal(5190000000L * 1.0);

Output:
5190000000

What is it? and how does F parameter make mistake?I really confused!!!!

EDIT

The version of jdk is 1.8

reza ramezani matin
  • 1,384
  • 2
  • 18
  • 41

4 Answers4

3

Before the BigDecimal is constructed, the expression inside the brackets needs to be evaluated first.

So, 5190000000 * 1.0F gets evaluated to a float value, but that value is not exactly 5190000000. Why? Because 5190000000 cannot be accurately represented in float. Some precision is lost already, before the BigDecimal is created. Therefore, the output you see is not accurate.

In the second case, 5190000000 * 1.0 gets evaluated to a double, and double has enough precision to represent 5190000000 accurately. Why does it get evaluated to a double this time?, you might ask. Because 1.0F is a float literal, and 1.0 is a double literal. And that decides the type of the expression.

To get an accurate value, use the string constructor:

BigDecimal bd = new BigDecimal("5190000000");
bd = bd.multiply(BigDecimal.ONE); // if you insist on multiplying it by 1
Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

You should never create a BigDecimal using the double constructor. As the double (or float, in this case) you are passing in is imprecise to begin with, that imprecision will be reflected in the BigDecimal.

It is recommended that you either use the String or long constructors for BigDecimal, or the valueOf factory method, to initialize a BigDecimal, as these are more likely to retain the precision you need.

Joe C
  • 15,324
  • 8
  • 38
  • 50
1

This is expected behaviour. The expression 5190000000 * 1.0F is evaluated as a float, which has only 6 to 7 decimal digits precision.

Actually, the value you eventually get is accurate to 7 digits.

Henry
  • 42,982
  • 7
  • 68
  • 84
0

reason - The construction method of BigDecimal, the parameter type is double. - So, your first code will be make implicit convert by compiler that will make some problem of lose accuracy. - But, your second code '1.0' the type default is double, so that is correct. - Other thing, the int type the max value is 2147483647, your set parameter is 5190000000 that will be make compile error.

Bond Zhou
  • 21
  • 1