[疯狂Java]基础类库:BigDecimal(精确实数)

本文介绍了Java中用于处理精确实数的BigDecimal类,包括其突破整型和浮点型精度限制的优势,以及使用字符串和基本类型构造BigDecimal的方法。文章详细讲解了转换为基本类型、算术运算(如加减乘除、指数运算)、取模运算及其特殊情况,特别是除法时如何控制精度和取舍方式。
摘要由CSDN通过智能技术生成

1. BigDecimal简介:

    1) 用Java的基础类型来表示数据还是有一定的局限性的:

         i. 对于整型最明显的就是存在界限问题,由于使用有限位二进制数来表示整型,必定存在上下限,不能表示更大范围的数了;

         ii. 对于浮点型就不用说了,根本无法精确表示,例如一个字面值0.1也无法在底层用二进制精确表示!

    2) BigDecimal——精确实数:

         i. Java提供BigDecimal类来表示精确实数;

         ii. 它底层使用字符串来保存数字的,而字符串的位数不受限制,这就首先突破了整型界限的问题;

         iii. 其次,同样是由于用字符串来保存数字的,对于浮点数其小数部分可以精确到最低位;


2. 构造:

    1) 首推用字符串来构造:毕竟本身底层即使用字符串保存的

         i. BigDecimal(String val);

         ii. BigDecimal(char[] val);

         iii. BigDecimal(char[] val, int offset, int len);

!!分别用String和字符数组来构造,例如:BigDecimal num = new BigDecimal("0.123");

    2) 当然也可以用基本类型来构造:

         i. BigDecimal(int | long | double val);  // 只支持这三种类型

         ii. 也可以用其静态工具方法来构造:static BigDecimal BigDecimal.valueOf(long | double val);  // 只支持long和double

!!但是double版本的最好不要用!!因为double本身就是不精确的,转换成BigDecimal同样是不精确的!!(转换的方法就是取其字符串表示形式)


3. 转换成基本类型:

    1) 当然也允许将BigDecimal类型转换成相应的基本类型;

    2) 对于整型:type typeValue[Exact]();  // type支持byte、short、int、long

         i. 这里转换的时候问题又两个,一个是BigDecimal表示的是实数,可能有小数点,另一个时转换成相应的整型时可能会溢出;

         ii. 没有Exact的版本遇到上面两个问题没有异常,直接截断处理(这可能会导致后续程序的错误);

         iii. Exact的版本遇到上面两个问题时会抛出异常!

!!通常使用第二个版本;


4. 算术运算:

    1) 二元运算:BigDecimal op(BigDecimal val);  // this op val

         i. 加:add

         ii. 减:subtract

         iii. 乘:multiply

!!除法非常特殊,最后详解

    2) 指数运算:BigDecimal pow(int n);  // this ^ n

    3) 一元运算:

         i. 绝对值:BigDecimal abs();

         ii. 取反(加一个负号):BigDecimal negate();

         iii. 信号采样:int signum();  // 负数返回-1,正数1,0返回0

         iv. 自加(自己加自己,不是加1):BigDecimal plus();

    4) 除法为什么特殊:

         i. BigDecimal表示精确实数,因此其进行运算之后得到的结果也希望是精确实数,精确实数经过上述的所有运算之后得到的结果必然也是精确的,但是除法就不一定了;

         ii. 最简单的就是1 / 3得到的就是无限循环的0.333...,对于无限循环小数BigDecimal再精确也无法表示了,因为不可能存无限个3啊!!

         iii. 考虑到这个问题,BigDecimal的除法divide就需要考虑精度问题了!

         iv. 因此除法通常含有控制精度的参数;

    5) 除法:

         i. 完整版:BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode);

            a. divisor是除数,scale是精度(小数点后保留几位),roundingMode是取舍方式;

            b. 取舍方式:都是BigDecimal中定义的静态常量,常用的有

HALF_UP:四舍五入

CEILING:取上限

FLOOR:取下限

UNNECESSARY:没必要取舍,这就意味着得到的结果一定是精确的、不会有无限循环的,但是一旦有就会抛出异常!!

         ii. BigDecimal divide(BigDecimal divisor, int roundingMode);  // 精度使用默认值,取舍方式自己决定

         iii. BigDecimal divide(BigDecimal divisor); // 精度默认,取舍方式默认是UNNECESSARY,因此小心抛出异常哦!!

    6) 既然有除法,必然有模除咯!

         i. 首先要知道整除(即结果只取除法结果的整数部分):BigDecimal divideToIntegralValue(BigDecimal divisor); // 定义为a \ b

         ii. 接着就是模除:BigDecimal remainder(BigDecimal divisor); // 理论上就是a % b

!!但是BigDecimal表示的是实数,因此两个操作数都可能有小数点,而这里的模除是广义模除,其运算方法就是 a - (a \ b) × b,因此结果很可能也有小数点,并且也可能是负数!

    7) 还有同时得到除数和余数的方法:BigDecimal[] divideAndRemainder(BigDecimal divisor);  // 把上面两个方法分别放在[0]和[1]中一块儿返回(先\结果,后%结果)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值