BigDecimal 精度和比例

我在应用程序中使用 BigDecimal 表示数字,例如,使用 JPA。我做了一些关于术语“精度”和“规模”的研究,但我不知道它们到底是什么。

有人能解释一下 BigDecimal 值的“精度”和“比例”的含义吗?

@Column(precision = 11, scale = 2)

谢谢!

121972 次浏览

Quoting Javadoc:

The precision is the number of digits in the unscaled value.

and

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.

  • Precision: Total number of significant digits

  • Scale: Number of digits to the right of the decimal point

See BigDecimal class documentation for details.

From your example annotation the maximum digits is 2 after the decimal point and 9 before (totally 11): 123456789,01

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 unscaledValue*10^{-scale}.

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 10^{-scale}.

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 >= 0 and precision - scale -1 >= -6 a 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 -1 equals unscaledValue*10^{-scale} is 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 is the total number of significant digits in a number. Scale is the number of digits to the right of the decimal point.

Examples:

123.456 Precision=6 Scale=3

10 Precision=2 Scale=0

-96.9923 Precision=6 Scale=4

0.0 Precision=1 Scale=1

Negative Scale

For a negative scale value, we apply the following formula: result = (given number) * 10 ^ (-(scale value)) Example

Given number = 1234.56

scale = -5

-> (1234.56) * 10^(-(-5))

-> (1234.56) * 10^(+5)

-> 123456000

Reference: https://www.logicbig.com/quick-info/programming/precision-and-scale.html