BigDecimal、精度和小数位数

问题描述 投票:0回答:7

我在应用程序中使用 BigDecimal 来表示数字,例如使用 JPA。我对“精度”和“规模”这两个术语做了一些研究,但我不明白它们到底是什么。

任何人都可以向我解释 BigDecimal 值的“精度”和“小数位数”的含义吗?

@Column(precision = 11, scale = 2)

谢谢!

java jpa scale precision bigdecimal
7个回答
176
投票

A

BigDecimal
由两个值定义:任意精度整数和 32 位整数 scale
BigDecimal
的值定义为 unscaledValue*10^{-scale}.

精度:

精度是未缩放值中的位数。 例如,对于数字 123.45,返回的精度为 5。

所以, precision表示任意精度整数的长度。以下是一些具有相同比例但不同精度的数字示例:

  • 12345 / 100000 = 0.12345 // 小数位数 = 5,精度 = 5
  • 12340 / 100000 = 0.1234 // 小数位数 = 4,精度 = 4
  • 1 / 100000 = 0.00001 // 小数位数 = 5,精度 = 1

在数字等于 0(即 0.000)的特殊情况下,精度始终为 1。

规模:

如果为零或正数,则scale是小数点右侧的位数。如果为负,则该数字的未缩放值乘以 10 的缩放负次方。例如,标度为 -3 表示未标度值乘以 1000。

这意味着“BigDecimal”的整数值乘以10^{-scale}

以下是相同精度、不同比例的几个示例:

  • 12345,标度 5 = 0.12345
  • 12345,标度 4 = 1.2345
  • 12345,刻度为 0 = 12345
  • 12345 带刻度 -1 = 123450

BigDecimal.toString:

toString
BigDecimal
方法根据比例和
precision
的行为有所不同。 (感谢@RudyVelthuis 指出了这一点。)

  • 如果
    scale == 0
    ,则直接按原样打印出整数。
  • 如果
    scale < 0
    ,则始终使用 E 表示法(例如 5 刻度 -1 生成“5E+1”)
  • 如果
    scale >= 0
    precision - scale -1 >= -6
    生成一个普通的十进制数(例如 10000000 标度 1 生成“1000000.0”)
  • 否则,使用 E 表示法,例如10 标度 8 产生“1.0E-7”,因为
    precision - scale -1
    等于 unscaledValue*10^{-scale} 小于 -6。

更多示例:

  • 19/100 = 0.19 // 整数=19,小数位数=2,精度=2
  • 1/1000 = 0.0001 // 整数=1,小数位数=4,精度=1

95
投票
  • 精度:有效数字总数

  • 刻度:小数点右侧的位数

有关详细信息,请参阅

BigDecimal
类文档。


7
投票

精度是数字中有效数字的总数。 刻度是小数点右侧的位数。

示例:

123.456 精度=6 刻度=3

10 精度=2 刻度=0

-96.9923 精度=6 刻度=4

0.0 精度=1 尺度=1

负尺度

对于负比例值,我们应用以下公式: 结果 = (给定数字) * 10 ^ (-(刻度值)) 示例

给定数字 = 1234.56

比例=-5

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

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

-> 123456000

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


4
投票

引用Javadoc

精度是未缩放值中的位数。

如果为零或正数,则小数位数为小数点右侧的位数。如果为负数,则该数字的未缩放值乘以 10 的缩放负次方。例如,标度为 -3 表示未标度值乘以 1000。


3
投票

从您的示例注释中,最大数字为小数点后 2 位和小数点前 9 位(总共 11 位):

123456789,01


0
投票

@Column(precision = 11, scale = 2)
变量的JPA注释
BigDecimal
在MYSQL数据库中转换为
DECIMAL(11,2)

这意味着该列总共可以存储 11 位数字,小数点后允许保留 2 位数字。 IE。这里的范围是

[-999999999.99,999999999.99]


0
投票
public static long[] toFraction(double number) {
    final BigDecimal bigDecimal = BigDecimal.valueOf(number);
    final int decimalPlaces = bigDecimal.scale();
    final BigDecimal divisor = BigDecimal.TEN.pow(decimalPlaces);
    final BigDecimal dividend = bigDecimal.movePointRight(decimalPlaces);
    final BigInteger divisorInt = BigInteger.valueOf(divisor.longValue());
    final BigInteger dividendInt = BigInteger.valueOf(dividend.longValue());
    final BigInteger greatestCommonDivisor = divisorInt.gcd(dividendInt);
    return new long[] {
            dividendInt.divide(greatestCommonDivisor).longValue(), 
            divisorInt.divide(greatestCommonDivisor).longValue(), 
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.