A BigDecimal is defined by two values: an arbitrary precision integer and a 32-bit integer scale. The value of the BigDecimal is defined to be .
Precision:
The precision is the number of digits in the unscaled value. For instance, for the number 123.45, the precision returned is 5.
So, precision indicates the length of the arbitrary precision integer. Here are a few examples of numbers with the same scale, but different precision:
- 12345 / 100000 = 0.12345 // scale = 5, precision = 5
- 12340 / 100000 = 0.1234 // scale = 4, precision = 4
- 1 / 100000 = 0.00001 // scale = 5, precision = 1
In the special case that the number is equal to zero (i.e. 0.000), the precision is always 1.
Scale:
If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale. For example, a scale of -3 means the unscaled value is multiplied by 1000.
This means that the integer value of the ‘BigDecimal’ is multiplied by .
Here are a few examples of the same precision, with different scales:
- 12345 with scale 5 = 0.12345
- 12345 with scale 4 = 1.2345
- …
- 12345 with scale 0 = 12345
- 12345 with scale -1 = 123450 †
BigDecimal.toString:
The toString method for a BigDecimal behaves differently based on the scale and precision. (Thanks to @RudyVelthuis for pointing this out.)
- If
scale == 0, the integer is just printed out, as-is. - If
scale < 0, E-Notation is always used (e.g. 5 scale -1 produces "5E+1") - If
scale >= 0andprecision - scale -1 >= -6a plain decimal number is produced (e.g. 10000000 scale 1 produces "1000000.0") - Otherwise, E-notation is used, e.g. 10 scale 8 produces "1.0E-7" since
precision - scale -1equalsis less than -6.
More examples:
- 19/100 = 0.19 // integer=19, scale=2, precision=2
- 1/1000 = 0.0001 // integer=1, scale = 4, precision = 1
A BigDecimal is defined by two values: an arbitrary precision integer and a 32-bit integer scale. The value of the BigDecimal is defined to be .
Precision:
The precision is the number of digits in the unscaled value. For instance, for the number 123.45, the precision returned is 5.
So, precision indicates the length of the arbitrary precision integer. Here are a few examples of numbers with the same scale, but different precision:
- 12345 / 100000 = 0.12345 // scale = 5, precision = 5
- 12340 / 100000 = 0.1234 // scale = 4, precision = 4
- 1 / 100000 = 0.00001 // scale = 5, precision = 1
In the special case that the number is equal to zero (i.e. 0.000), the precision is always 1.
Scale:
If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale. For example, a scale of -3 means the unscaled value is multiplied by 1000.
This means that the integer value of the ‘BigDecimal’ is multiplied by .
Here are a few examples of the same precision, with different scales:
- 12345 with scale 5 = 0.12345
- 12345 with scale 4 = 1.2345
- …
- 12345 with scale 0 = 12345
- 12345 with scale -1 = 123450 †
BigDecimal.toString:
The toString method for a BigDecimal behaves differently based on the scale and precision. (Thanks to @RudyVelthuis for pointing this out.)
- If
scale == 0, the integer is just printed out, as-is. - If
scale < 0, E-Notation is always used (e.g. 5 scale -1 produces "5E+1") - If
scale >= 0andprecision - scale -1 >= -6a plain decimal number is produced (e.g. 10000000 scale 1 produces "1000000.0") - Otherwise, E-notation is used, e.g. 10 scale 8 produces "1.0E-7" since
precision - scale -1equalsis less than -6.
More examples:
- 19/100 = 0.19 // integer=19, scale=2, precision=2
- 1/1000 = 0.0001 // integer=1, scale = 4, precision = 1
Precision: Total number of significant digits
Scale: Number of digits to the right of the decimal point
See BigDecimal class documentation for details.
One important point that is alluded to but not directly addressed is the difference between "precision" and "scale" and how they are used in the two statements. "precision" is the total number of significant digits in a number. "scale" is the number of digits to the right of the decimal point.
The MathContext constructor only accepts precision and RoundingMode as arguments, and therefore scale is never specified in the first statement.
setScale() obviously accepts scale as an argument, as well as RoundingMode, however precision is never specified in the second statement.
If you move the decimal point one place to the right, the difference will become clear:
// 1.
new BigDecimal("35.3456").round(new MathContext(4, RoundingMode.HALF_UP));
//result = 35.35
// 2.
new BigDecimal("35.3456").setScale(4, RoundingMode.HALF_UP);
// result = 35.3456
There is indeed a big difference, which you should keep in mind. setScale really set the scale of your number whereas round does round your number to the specified digits BUT it "starts from the leftmost digit of exact result" as mentioned within the jdk. So regarding your sample the results are the same, but try 0.0034 instead. Here's my note about that on my blog:
http://araklefeistel.blogspot.com/2011/06/javamathbigdecimal-difference-between.html