为什么BigDecimal比双精度更精确?

时间:2013-06-20 09:04:56

标签: java double bigdecimal

我想知道BigDecimaldouble之间的确切区别。我知道BigDecimaldouble更准确,您应该使用前者进行计算。

为什么它更精确?为什么不能自定义double以使其像BigDecimal一样工作?或者用double计算是否有任何优势?

8 个答案:

答案 0 :(得分:5)

BigDecimal

  

不可变,任意精度的带符号十进制数。 BigDecimal由任意精度整数非标度值和32位整数标度组成。如果为零或正数,则比例是小数点右侧的位数。如果是负数,则将数字的未缩放值乘以10来表示比例的否定。因此,BigDecimal表示的数字的值是(unscaledValue×10-scale)。

Double具有一定的精确度。

已编辑: BigDecimal是一个真实的对象,而不是一个原始对象。因此,它抽象数字表示并且不受物理(读取存储器)限制的约束。 礼貌: Max Leske

答案 1 :(得分:2)

double是一种非常快速的浮点数据类型,在许多芯片组上以非常低的水平实现。

它的精度足以满足很多应用:例如测量太阳到冥王星的距离到最近的厘米!

在考虑转向更精确的数据类型时,始终是性能权衡,因为后者会慢得多,而您最喜欢的数学库可能不支持它们。请记住,程序的输出是输入质量的函数。

作为最后的评论,不要使用双倍代表现金数量!

答案 2 :(得分:1)

double有8个字节来表示该值,其精度限制为15个十进制数字,请参阅http://en.wikipedia.org/wiki/IEEE_754-1985。 BigDecimal精度实际上是无限制的,因为它基于任意长度的int数组。虽然使用double的操作比使用BigDecimal快得多,但是这种数据类型永远不应该用于精确值,例如货币。

答案 3 :(得分:1)

BigDecimal上执行操作时,结果中的位数通常会大于任一操作数。这有两个主要影响:

  1. 除非代码强制定期舍入,否则BigDecimal上的操作会随着数字越来越长而变得越来越慢。

  2. 没有固定大小的容器可能足够大以容纳BigDecimal,因为填充各自容器的两个值之间的许多操作会产生太长的结果以适应容器大小

  3. floatdouble可以快速的基本原因是,BigDecimal不能,它们被定义为在任何计算中都需要尽可能多的精度,以便产生一个与原始操作数相同的容器大小。这使他们能够使用固定大小的容器,而不必担心后续操作变得越来越慢。

    顺便说一下,BigDecimal慢的另一个主要(虽然不那么基本)的原因是值使用二进制格式的尾数表示,但是十进制指数。因此,任何需要调整其操作数精度的操作都必须先进行非常昂贵的“标准化”步骤。如果任何给定值只有一个表示,则类型可能更容易使用,因此将123.456添加到0.044得到123.5而不是123.500,但将123.500归一化到123.5将需要比添加123.456和0.44更多的计算;此外,如果将结果添加到小数点后面有三个有效数字的另一个数字,则在较早添加之后执行的归一化将增加执行下一个数字所需的时间。

答案 4 :(得分:1)

  

为什么BigDecimal更精确?

  1. 内存中双倍大小的固定为64位(8字节)。这将其限制为精度的15到17个十进制数字。 BigDecimal可以增长到你需要的任何大小。

  2. Double以二进制运算,这意味着它只能精确地表示可以二进制表示为有限数的数字。例如,二进制中的0.375正好是0.011。 (换句话说,它是2的幂的总和:它是2 -2 + 2 -3 。)但是像0.1这样的数字不能精确地表示作为double,因为在二进制中它是0.0001100110011...,它不会终止。 BigDecimal以十进制运算,因此它可以精确地表示我们在十进制中熟悉的数字,例如0.1。 (但是,虽然这扩展了可精确表示的值的范围,但它并没有消除潜在的问题;例如,值三分之一无法用任何一种类型精确表示,因为它具有非以二进制(0.010101 ...)和十进制(0.33333 ...)结束扩展。)

  3.   

    用double计算是否有任何优势?

    绝对!

    1. 由于内存占用的内存相对较少,因此double更适合长数组。

    2. Double的固定二进制格式使其更快。它可以在软件和硬件中有效地处理。 CPU在专用电路中实现双重算法。

    3. 使用BigDecimal,对象可以在内存中任意增长,因为重复计算可以产生更长的分数,但这不是你需要担心的问题,因为它的大小是固定的。

    4.   

      为什么不能自定义double以使其像BigDecimal一样工作?

      你得到你付出的代价。 BigDecimal可以更强大,但它的复杂性使计算速度变慢,需要更多内存,而且使用起来更复杂。没有满足所有用例的数字数据类型,因此您必须根据应用程序的需要选择所需的数据类型。

答案 5 :(得分:0)

使用double进行计算比使用BigDecimal快得多,因为它是一种主要类型,您还可以轻松获得全方位的数学运算。

BigDecimal非常棒,如果您需要执行非常精确的计算,但是您需要为此付出代价,例如无法轻松访问实际适用于BigDecimal的平方根函数,并且速度通常要慢得多计算

答案 6 :(得分:0)

由于我遇到Double的问题是它的精度值是有限的,所以当你使用精度超过限制时,该值将被四舍五入,但是在Big Decimal的情况下你将不会遇到这个问题

答案 7 :(得分:0)

根据定义,double具有固定的精度(基数2为53位)。它的主要优点是它非常快,因为在实践中基本操作完全用硬件实现。如果这样的精度和/或基数2不适合您的应用程序,则可以使用任意精度算术。 BigDecimal是标准版,并使用基数10.但现在GNU MPFR Java bindings(我还没有尝试过),以便您可以使用GNU MPFR库进行计算2应该明显快于BigDecimal