我想知道BigDecimal
和之间的确切区别double
。我知道这比前者BigDecimal
更精确double
,您应该使用前者进行计算。
为什么更精确?为什么不能自定义double
使其像 一样工作BigDecimal
?或者用 计算有什么好处double
?
我想知道BigDecimal
和之间的确切区别double
。我知道这比前者BigDecimal
更精确double
,您应该使用前者进行计算。
为什么更精确?为什么不能自定义double
使其像 一样工作BigDecimal
?或者用 计算有什么好处double
?
double 是在许多芯片组上以非常低的级别实现的非常快的浮点数据类型。
它的精度足以满足很多应用:例如测量太阳到冥王星的距离,精确到厘米!
在考虑迁移到更精确的数据类型时总是需要权衡性能,因为后者会慢得多,而且您最喜欢的数学库可能不支持它们。请记住,程序的输出是输入质量的函数。
最后一点,千万不要使用双精度数来表示现金数量!
double 有 8 个字节来表示该值,其精度限制为 15 个十进制数字,请参见http://en.wikipedia.org/wiki/IEEE_754-1985。BigDecimal 精度实际上是无限的,因为它基于任意长度的 int 数组。尽管使用 double 的操作比使用 BigDecimal 快得多,但这种数据类型绝不应该用于精确值,例如货币。
当对 执行操作时BigDecimal
,结果中的位数通常会大于任一操作数。这有两个主要影响:
除非代码强制定期舍入,否则随着数字越来越长,操作BigDecimal
会越来越慢。
没有固定大小的容器可能大到足以容纳 a BigDecimal
,因为填充其各自容器的两个值之间的许多操作会产生太长的结果而无法放入该大小的容器中。
float
并且double
可以快速但不能快速的根本原因BigDecimal
是它们被定义为在任何计算中尽可能多地降低精度,以产生与原始操作数相同大小的容器的结果。这使他们能够使用固定大小的容器,而不必担心后续操作会变得越来越慢。
顺便说一句,另一个缓慢的主要(尽管不太基本)原因BigDecimal
是值使用二进制格式的尾数表示,但使用十进制指数。因此,任何需要调整其操作数精度的操作都必须在一个非常昂贵的“规范化”步骤之前进行。如果任何给定值只有一种表示形式,则该类型可能更易于使用,因此将 123.456 与 0.044 相加得到 123.5 而不是 123.500,但将 123.500 归一化为 123.5 比将 123.456 和 0.44 相加需要更多的计算;此外,如果将该结果与小数点后三位有效数字相加,则在较早的相加之后执行的标准化将增加执行下一个所需的时间。
为什么 BigDecimal 更精确?
Double 在内存中的大小固定为 64 位(8 字节)。这将其精度限制为 15 到 17 位十进制数字。BigDecimal 可以增长到您需要的任何大小。
Double 以二进制运行,这意味着它只能精确地表示可以表示为二进制有限数的数字。例如,二进制的 0.375 正好是 0.011。(换句话说,它是 2 的幂的和:它是 2 -2 + 2 -3。)但是像 0.1 这样的数字不能精确地表示为双精度数,因为在二进制中它是0.0001100110011...,这不会终止。BigDecimal 以十进制运行,因此它可以精确地表示 0.1 等我们熟悉的十进制数字。(然而,虽然这扩大了精确可表示值的范围,但它并没有消除潜在的问题;例如,三分之一的值不能用任何一种类型精确表示,因为它在二进制 (0.010101...) 和十进制 (0.33333...) 中都有非终止扩展。)
用双精度计算有什么好处吗?
绝对地!
由于它占用的内存相对较少,因此 double 更适合长数组。
Double 的固定二进制格式使其速度更快。它可以在软件和硬件上有效地处理。CPU 在专用电路中实现双重算术。
使用 BigDecimal,对象可以在内存中任意增长,因为重复计算可以产生越来越长的分数,但是对于 double,这不是您需要担心的事情,因为它的大小是固定的。
为什么不能自定义 double 以便它像 BigDecimal 一样工作?
你得到你所付出的。BigDecimal 可以更强大,但它的复杂性使计算速度变慢,占用更多内存,使用起来也更复杂。没有满足所有用例的数字数据类型,因此您必须根据应用程序的需要选择您想要的数据类型。
计算double
比 with 快得多,BigDecimal
因为它是一种原始类型,您还可以轻松完成所有数学运算。
BigDecimal
BigDecimal
如果您需要执行非常精确的计算,但您为此付出了代价,例如无法轻松访问实际适用于 a且通常要慢得多的计算的平方根函数,这很好。
由于我遇到的问题 Double 是它的精度值是有限的,所以当你使用超过限制的精度时,值将被四舍五入,但在 Big Decimal 的情况下你不会遇到这个问题
根据定义,double
具有固定精度(以 2 为基数的 53 位)。它的主要优点是速度非常快,因为实际上基本操作完全在硬件中实现。如果这样的精度和/或基数 2 不适合您的应用程序,您可以使用任意精度算术。BigDecimal
是标准的并使用基数 10。但是现在有GNU MPFR Java 绑定(我没有尝试过),因此您可以使用GNU MPFR库进行计算,该库使用基数 2 并且应该比BigDecimal
.