“This is the first day of my participation in the Gwen Challenge in November. See details of the event: The last Gwen Challenge in 2021”.

I encountered a gorgon problem with BigDecimal division, which returned 0 for what was supposed to be an accurate calculation, but of course it turned out to be the wrong gesture, so note this to avoid the same problem later

I. Questions thrown

When doing high-precision division with BigDecimal, you encounter a minor problem, as follows

@Test
public void testBigDecimal(a) {
    BigDecimal origin = new BigDecimal(541253);
    BigDecimal now = new BigDecimal(12389431);

    BigDecimal val = origin.divide(now, RoundingMode.HALF_UP);
    System.out.println(val);

    origin = new BigDecimal(541253);
    now = new BigDecimal(12389431.3);
    val = origin.divide(now, RoundingMode.HALF_UP);
    System.out.println(val);

    origin = new BigDecimal(541253.4);
    now = new BigDecimal(12389431);
    val = origin.divide(now, RoundingMode.HALF_UP);
    System.out.println(val);
}
Copy the code

What is the output from above?

0
0
0.043686703610520937021487456961257
Copy the code

Why are the first two zeros? It would be understandable if 541253/12389431 = 0, but BigDecimal is not a highly accurate computation

We know that we can specify decimal-preserving parameters when BigDecimal is triggered. Would it make a difference if we added this?

BigDecimal origin = new BigDecimal(541253);
BigDecimal now = new BigDecimal(12389431);

BigDecimal val = origin.divide(now, 5, RoundingMode.HALF_UP);
System.out.println(val);
Copy the code

The output is:

0.04369
Copy the code

Therefore, there is no problem after the reserved decimal is specified. Therefore, it is a bold guess that in the above several cases, the default value is different when the scale value is not specified, resulting in different precision of the final result.

Divide (now, RoundingMode.HALF_UP); divide(now, RoundingMode.HALF_UP); So the scale argument is aimed at the Origin object, and the object has to analyze its construction because there’s nothing else to use

II. Source location

1. Shaping parameter transmission structure

Analyze the following line and go directly to the source code

BigDecimal origin = new BigDecimal(541253);
Copy the code

Int pass-by: int pass-by: int

// java.math.BigDecimal#BigDecimal(int)
public BigDecimal(int val) {
    this.intCompact = val;
    this.scale = 0;
    this.intVal = null;
}

public BigDecimal(long val) {
    this.intCompact = val;
    this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
    this.scale = 0;
}
Copy the code

So, the default scale is 0, that is, when origin is a positive number, it is impossible to divide the scale parameter with it, and it will return no decimal

2. Floating point parameter transmission

Next is the floating point scale default value confirmation, this construction compared to the previous complex point, the source code is not posted, too long, also do not understand what to do, directly use a trivial way, into the debug mode, single step execution

@Test
public void testBigDecimal(a) {
    BigDecimal origin = new BigDecimal(541253.0);
    BigDecimal now = new BigDecimal(12389431.1);
    BigDecimal tmp = new BigDecimal(0.0);
}
Copy the code

According to the debug result, the first one, scale is 0; The second scale is 29, and the third scale is 0

3. The String arguments

It is still a large string of logic, also use the single-step debug mode to try

@Test
public void testBigDecimal(a) {
    BigDecimal origin = new BigDecimal("541253.0");
    BigDecimal now = new BigDecimal("12389431.1");
    BigDecimal t = new BigDecimal("0.0");
}
Copy the code

All three of them have a scale of 1

4. Summary

  • When dividing BigDecimal, it is best to specify its scale parameter, otherwise a pit may occur
  • How is BigDecimla’s scale initialization implemented

I’ll close with a diagram of multiplication

Series of blog posts:

  • Practical tip 1: String placeholder replacement -JDK version
  • Practice Tip 2: Array and list are rotated
  • Practice Tip 3: String and container transfer
  • Practical tip 4: Elegant string concatenation implementation
  • Practice tip 5: Hump and underline turn each other
  • Practice Tip 6: Special use of enumeration
  • Practice Tip 7: Sort carefully
  • Practice tip 8: Specify the initial size of the container
  • List. SubList is used incorrectly StackOverflowError
  • Practice Tip # 10: Immutable containers
  • Practice Tip 11: Array copy
  • Practice Tip 12: Number formatting
  • Practice Tip 13: Base conversion is easy
  • Practice Tip 14: Configure file Properties
  • How to determine the basic type or basic type of packaging class
  • Practice Tips 17: How to choose random number generation

II. The other

1. A gray Blog:liuyueyi.github.io/hexblog

As far as the letter book is better than no book, the content has been, purely one’s opinion, due to the limited personal ability, it is hard to avoid omissions and mistakes, such as finding bugs or better suggestions, welcome criticism and correction, not grudging gratitude

  • Micro Blog address: Small Gray Blog
  • QQ: a gray /3302797840
  • Wechat official account: One Grey Blog