As per the documentation, divide(BigDecimal divisor, RoundingMode roundingMode)
returns a BigDecimal
whose value is (this / divisor), and whose scale is this.scale()
.
Why did you get the expected result for 21099000.1 / 13196000.1?
Check the result of the following code:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main {
public static void main(String[] args) {
BigDecimal first = BigDecimal.valueOf(21099000.1);
BigDecimal second = BigDecimal.valueOf(13196000.1);
System.out.println("First: " + first + ", Scale: " + first.scale());
System.out.println("Second: " + second + ", Scale: " + second.scale());
// 21099000.0 / 13196000.0 = 1.5988936041
System.out.println(BigDecimal.valueOf(1.5988936041).setScale(first.scale(), RoundingMode.HALF_UP));
}
}
Output:
First: 21099000.1, Scale: 1
Second: 13196000.1, Scale: 1
1.6
As you can see, JVM has chosen the scale as 1
for first
and thus the result of divide
(which is 1.5988936041
) is also set as 1
which is equal to 1.6
with RoundingMode.HALF_UP
.
Why did you not get the expected result for 21099000.0 / 13196000.0?
Check the result of the following code:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main {
public static void main(String[] args) {
BigDecimal first = BigDecimal.valueOf(21099000.0);
BigDecimal second = BigDecimal.valueOf(13196000.0);
System.out.println("First: " + first + ", Scale: " + first.scale());
System.out.println("Second: " + second + ", Scale: " + second.scale());
// 21099000.0 / 13196000.0 = 1.5988936041
System.out.println(BigDecimal.valueOf(1.5988936041).setScale(first.scale(), RoundingMode.HALF_UP));
}
}
Output:
First: 2.1099E+7, Scale: -3
Second: 1.3196E+7, Scale: -3
0E+3
As you can see, JVM has chosen the scale as -3
for first
and thus the result of divide
(which is 1.5988936041
) is also set as -3
which is equal to 0
(or 0E+3
) with RoundingMode.HALF_UP
.
How can I change this behavior?
As mentioned in the documentation, scale of the division is set as this.scale()
which means if you set the scale of first
to 1
, you can get the expected result.
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main {
public static void main(String[] args) {
BigDecimal first = BigDecimal.valueOf(21099000.0).setScale(1);
BigDecimal second = BigDecimal.valueOf(13196000.0);
System.out.println("First: " + first + ", Scale: " + first.scale());
System.out.println("Second: " + second + ", Scale: " + second.scale());
System.out.println("Division: " + first.divide(second, RoundingMode.HALF_UP).doubleValue());
}
}
Output:
First: 21099000.0, Scale: 1
Second: 1.3196E+7, Scale: -3
Division: 1.6
What is the most common way?
The last example worked well and there is no problem using it. However, the most common way is to use divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
.
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main {
public static void main(String[] args) {
BigDecimal first = BigDecimal.valueOf(21099000.0);
BigDecimal second = BigDecimal.valueOf(13196000.0);
System.out.println("First: " + first + ", Scale: " + first.scale());
System.out.println("Second: " + second + ", Scale: " + second.scale());
System.out.println("Division: " + first.divide(second, 1, RoundingMode.HALF_UP).doubleValue());
}
}
Output:
First: 2.1099E+7, Scale: -3
Second: 1.3196E+7, Scale: -3
Division: 1.6