Java高精度——BigDecimal

BigDecimal

B i g D e c i m a l BigDecimal BigDecimal 由任意精度的整数非标度值和 32 32 32 位的整数标度 ( s c a l e scale scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 10 10 的负 s c a l e scale scale 次幂。因此, B i g D e c i m a l BigDecimal BigDecimal 表示的数值是( unscaledValue*10-scale)。

二、构造函数

第一种:把 d o u b l e double double 转化为 B i g D e c i m a l BigDecimal BigDecimal

BigDecimal(double val);

第二种:把String转化为BigDecimal

BigDecimal(String val);

使用 B i g D e c i m a l BigDecimal BigDecimal 要用 S t r i n g String String 来够造,要做一个加法运算,需要先将两个浮点数转为 S t r i n g String String ,然后够造成 B i g D e c i m a l BigDecimal BigDecimal,在其中一个上调用 a d d add add 方法,传入另一个作为参数,然后把运算的结果( B i g D e c i m a l BigDecimal BigDecimal)再转换为浮点数。由于 d o u b l e double double 类型精度不够精确,若直接传入 d o u b l e double double 类型结果不会和预期相同,因此创建对象时使用String类型。

三、运算
BigDecimal add(BigDecimal val) //BigDecimal 加法 

BigDecimal subtract (BigDecimal val) //BigDecimal 减法 

BigDecimal multiply (BigDecimal val) //BigDecimal 乘法 

BigDecimal divide (BigDecimal val, int scale, RoundingMode mode) 
//除法,第二个参数是精度值,第三个参数是保留小数位的规则(比如四舍五入)。后面两个参数可以不传入,但是当出现无限循环小数时必须传入两个参数。一般情况是传入了第二个参数就得传入第三个参数,一般是BigDecimal.ROUND_HALF_UP。

加减乘除其实最终都返回的是一个新的BigDecimal对象,因为BigInteger与BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象

四、BigDecimal的setScale方法

B i g D e c i m a l . s e t S c a l e ( ) BigDecimal.setScale() BigDecimal.setScale() 方法用于格式化小数点,需要注意的是它不会直接在原对象上面发生改变,需要赋值到一个新的对象。

表示保留6位小数,用四舍五入方式:$BigDecimal b = a.setScale(6,BigDecimal.ROUND_HALF_UP) $

直接删除多余的小数位,如2.35会变成2.3: B i g D e c i m a l b = a . s e t S c a l e ( 1 , B i g D e c i m a l . R O U N D _ D O W N ) BigDecimal b = a.setScale(1,BigDecimal.ROUND\_DOWN) BigDecimalb=a.setScale(1,BigDecimal.ROUND_DOWN)

注意:

s c a l e scale scale 指的是小数点后的位数

s c a l e ( ) scale() scale() 就是 B i g D e c i m a l BigDecimal BigDecimal 类中的方法。如:

BigDecimal b = new BigDecimal("123.456"); 
b.scale(); //返回的就是3
五、舍入模式
  • BigDecimal.Round_UP​ 远离零的舍入模式(向上舍入)。舍弃某部分时,若舍弃部分非零则对其前面的数字加1(此舍入模式始终不会减少计算值的大小)

0.833333… → 0.83334

  • BigDecimal.Round_DOWN​ 接近零的舍入模式(向下舍入)。直接丢弃需舍弃部分(此舍入模式始终不会增加计算值的大小)

0.833333… → 0.83333

  • BigDecimal.Round_CEILING 接近正无穷大的舍入模式。若BigDecimal为正,则舍入行为同ROUND_UP;若为负,则舍入行为同ROUND_DOWN(此舍入模式始终不会减少计算值大小)

0.833333… → 0.83334

-0.833333… → -0.83333

  • BigDecimal.Round_FLOOR 接近负无穷大(不是无穷小)的舍入模式。其行为与ROUND_CEILING相反,若BigDecimal为负,则舍入行为同ROUND_UP;若为正,则舍入行为同ROUND_DOWN(此舍入模式始终不会增加计算值大小)

0.833333… → 0.83333

-0.833333… → -0.83334

  • BigDecimal.Round_HALF_UP 向最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式(四舍五入,即舍弃部分>=0.5则向上舍入,否则向下舍入)

0.9166666… → 0.91667

0.833333… → 0.83333

  • BigDecimal.Round_HALF_DOWN 向最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向下舍入的舍入模式(舍弃部分<=0.5则向下舍入,否则向上舍入) 0.9166666… → 0.91667

0.833333… → 0.83333

  • BigDecimal.Round_HALF_EVEN 向最接近的数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入(在重复进行一系列计算时,此舍入模式可以将累加错误减到最小)

3.3333333… → 3.33333

0.9166666… → 0.91667

  • BigDecimal.Round_UNNECESSARY 断言请求的操作具有精确的结枚,因此不需要舍入,若该操作无精确结果(如1/3)则抛出 ArithmeticException

1 → 1.00000

0.333333… → ArithmeticException

六、其他

1.比较大小可以用 $a.compareTo(b) $

返回值

-1: 小于

0 :等于

1 :大于

2. B i g D e c i m a l BigDecimal BigDecimal 取其中最大、最小值、绝对值、相反数:

a.max (b) //比较取最大值

a.min(b) //比较取最小值

a.abs()//取最绝对值

a.negate()//取相反数
七、应用举例

2019年CCPC网络赛某题目,判断两个数相除是否为会产生无限小数。

这时我们应用 B i g D e c i m a l BigDecimal BigDecimal d i v i d e divide divide 方法,如果出现无限小数会抛出异常,这时我们可以接受异常再判断,是不是很简单

import java.math.BigDecimal;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		String s1, s2;
		Scanner scanner = new Scanner(System.in);
		s1 = scanner.next();
		s2 = scanner.next();
		BigDecimal b1 = new BigDecimal(s1);
		BigDecimal b2 = new BigDecimal(s2);
		try {
			b1 = b1.divide(b2);
			System.out.println("No");
		} catch (Exception e) {
			System.out.println("Yes");
		}	
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值