zoukankan      html  css  js  c++  java
  • java BigDecimal解析及注意事项

    BigDecimal简介

      JDK文档(中文)中的解释如下:

      不可变的、任意精度的有符号十进制数。BigDecimal 由任意精度的整数非标度值 和 32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。因此,BigDecimal 表示的数值是 (unscaledValue × 10-scale)。

    具体解释

      1.“BigDecimal 对象的值是不可变的”。这点在BigDecimal 对象的运算函数中表现了该特性:

    BigDecimal a = new BigDecimal("1.22");  
    System.out.println("construct with a String value: " + a);  
    BigDecimal b = new BigDecimal("2.22");  
    a.add(b);  
    System.out.println("a plus b is : " + a);

    我们很容易会认为会输出:

    construct with a Stringvalue:  1.22
    a plus b is :3.44

    但实际上a plus b is : 1.22

      2.“BigDecimal 由任意精度的整数非标度值 和 32 位的整数标度 (scale) 组成。如果标度值为零或正数,则标度是小数点后的位数”。这句话可以这样看:

      例如:-12 和 13.412

      表示为:-12 × 10-0 和13412 × 10-3

      这里用(非标度值 和 标度)表示分别为:[-12, 0]和[13412, 3]

      3.“如果标度值为负数,则将该数的非标度值乘以 10 的负 scale 次幂”。这句话可以这样看:

      例如:120.00

      该值表示为:12000 × 10-2

      这里用(非标度值 和 标度)表示分别为:[12000, 2]

      这里标度的值依然为正数2,但是进行进行下面操作:

    BigDecimal amount = new BigDecimal("-120.00");  
    //返回数值上等于此小数,但从该表示形式移除所有尾部零的 BigDecimal。  
    amount = amount.stripTrailingZeros(); 

      该值表示为:12 × 10-(-1)

      这里用(非标度值 和 标度)表示分别为:[12, -1]

    使用注意事项

      1.构造函数

    BigDecimal aDouble =new BigDecimal(1.22);  
    System.out.println("construct with a double value: " + aDouble);  
    BigDecimal aString = new BigDecimal("1.22");  
    System.out.println("construct with a String value: " + aString);

    输出结果如下:

    construct with a doublevalue:1.2199999999999999733546474089962430298328399658203125
    construct with a String value: 1.22

    JDK的描述:

    a)参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

    b)另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法。

    c)当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法。将double转换为String,也可以使用String的static方法:String.valueOf(double)。

     2.运算操作。加减乘除其实最终都返回的是一个新的BigDecimal对象,因为BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以a.add(b);虽然做了加法操作,但是a并没有保存加操作后的值,正确的用法应该是a=a.add(b);

    例子:

    判定BigDecimal 对象是否为整数:

    private boolean isIntegerValue(BigDecimal bd) {  
      return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0;  
    }

    为什么要这样做,请测试下下面这个例子:

    BigDecimal amount = new BigDecimal("-120.00");//请分别尝试"0", "0.00", "1.00","10.00"和"10.10"  
    System.out.println(amount.signum());//正负  
    System.out.println(amount.scale()); //标度  
    System.out.println(amount.stripTrailingZeros().scale());//去零后的标度
  • 相关阅读:
    封装成帧、帧定界、帧同步、透明传输(字符计数法、字符串的首尾填充法、零比特填充的首尾标志法、违规编码法)
    计算机网络之数据链路层的基本概念和功能概述
    物理层设备(中继器、集线器)
    计算机网络之传输介质(双绞线、同轴电缆、光纤、无线电缆、微波、激光、红外线)
    计算机网络之编码与调制
    0953. Verifying an Alien Dictionary (E)
    1704. Determine if String Halves Are Alike (E)
    1551. Minimum Operations to Make Array Equal (M)
    0775. Global and Local Inversions (M)
    0622. Design Circular Queue (M)
  • 原文地址:https://www.cnblogs.com/jiangds/p/7249426.html
Copyright © 2011-2022 走看看