BigDecimal类

目录

为什么会设计该类?

Float和Double类为什么会精度不够的情况?

是什么?

特点?

精度相关问题

常用方法

add()

subtract()

multiply()

divide()

compareTo()

setSCale()

doubleValue()、floatValue()、longValue()、intValue()等

abs()

toString()

toPlainString()

stripTrailingZeros()

BigDecimal常量

BigDecimal为什么会提供这些常量?

特定数值的常量

BigDecimal.ZERO

BigDecimal.ONE

BigDecimal.TEN

舍入模式常量

BigDecimal.ROUND_UP

BigDecimal.ROUND_DOWN


为什么会设计该类?

主要是为了解决 Float 和 Double 类精度不够的问题而设计的。

Float和Double类为什么会精度不够的情况?

主要是由于它们基于IEEE 754标准使用二进制表示浮点数。这种表示方法虽然能覆盖很大范围的数值,但并不能精确地表示所有的十进制小数。

具体来说,二进制浮点数表示法存在以下问题:(这里放一下实际代码例子)

  1. 无法精确表示某些十进制小数:例如,0.1在二进制中是一个无限循环小数,因此无法用有限长度的二进制小数精确表示。当尝试将这样的十进制小数转换为二进制浮点数时,会产生舍入误差。
  2. 运算时的精度损失:在进行浮点数运算时,如加法、减法、乘法或除法,这些舍入误差可能会累积,导致结果的不精确。特别是在多次运算后,误差可能会变得显著。
  3. 表示范围的限制:虽然FloatDouble类型能表示很大范围的数值,但在某些极端情况下,超出其表示范围的数值会导致溢出或下溢,从而影响精度。

PS:在进行需要高精度计算的场景,如金融计算和科学计算时,建议使用 BigDecimal 类而不是Float 或 Double 类。


是什么?

用于表示任意精度不可变的、任意精度的有符号十进制数


特点?

提供精确的浮点数运算,并且精度不是固定的,而是可以根据你的需要进行设置。当你创建一个BigDecimal 对象时,你可以选择指定其精度(即小数点后的位数)。


精度相关问题

BigDecimal 没有一个固定的默认精度。精度是根据你的使用情况和需求来设定的。

当创建一个新的 BigDecimal 对象时,你可以指定一个初始的精度(或称为标度,scale)。标度是小数点后的位数。如果你没有指定标度,那么 BigDecimal 会根据你提供的值来确定其标度。

BigDecimal bd1 = new BigDecimal("123.456"); // 标度为3,因为小数点后有3位  
BigDecimal bd2 = new BigDecimal("123");     // 标度为0,因为没有小数部分  
BigDecimal bd3 = new BigDecimal(123);       // 同样标度为0,因为整数可以视为没有小数部分的数

常用方法

add()

说明:将当前 BigDecimal 对象与另一个 BigDecimal 对象相加。

示例:

BigDecimal bd1 = new BigDecimal("10.0"); 
BigDecimal bd2 = new BigDecimal("5.0"); 
BigDecimal sum = bd1.add(bd2); // 结果为 15.0

subtract()

说明:从当前 BigDecimal 对象中减去另一个 BigDecimal 对象。

示例:

BigDecimal bd1 = new BigDecimal("10.0"); 
BigDecimal bd2 = new BigDecimal("5.0"); 
BigDecimal difference = bd1.subtract(bd2); // 结果为 5.0

multiply()

说明:将当前 BigDecimal 对象与另一个 BigDecimal 对象相乘。

例子:

BigDecimal bd1 = new BigDecimal("10.0"); 
BigDecimal bd2 = new BigDecimal("2.0"); 
BigDecimal product = bd1.multiply(bd2); // 结果为 20.0

divide()

说明:将当前 BigDecimal 对象除以另一个 BigDecimal 对象,并指定结果的小数位数和舍入模式。

示例:

BigDecimal bd1 = new BigDecimal("10.0"); 
BigDecimal bd2 = new BigDecimal("3.0"); 
BigDecimal quotient = bd1.divide(bd2, 2, RoundingMode.HALF_UP); // 结果为 3.33

compareTo()

说明:比较当前 BigDecimal 对象与另一个 Bigecimal 对象的大小。返回-1、0或1 分别表示小于、等于或大于。

示例:

BigDecimal bd1 = new BigDecimal("10.0"); 
BigDecimal bd2 = new BigDecimal("20.0"); 
int result = bd1.compareTo(bd2); // 结果为 -1,因为 10 小于 20

setSCale()

说明:设置BigDecimal对象的小数位数,并指定舍入模式。

示例:

BigDecimal bd = new BigDecimal("123.456789"); 
BigDecimal rounded = bd.setScale(2, RoundingMode.HALF_UP); // 结果为 123.46

doubleValue()、floatValue()、longValue()、intValue()等

说明:将Bigecimal转换为其他数值类型

示例:

BigDecimal bd = new BigDecimal("123"); 
double dblValue = bd.doubleValue(); // 结果为 123.0 
int intValue = bd.intValue(); // 结果为 123

abs()

说明:返回当前BigDecimal对象的绝对值。

示例:

BigDecimal bd = new BigDecimal("-10.0"); 
BigDecimal absValue = bd.abs(); // 结果为 10.0

toString()

说明:将BigDecimal转换为字符串(String)类型。

示例:

BigDecimal bd = new BigDecimal("123.456"); 
String strValue = bd.toString(); // 结果为 "123.456"

toPlainString()

说明:将BigDecimal转换为字符串(String)类型。

示例:

BigDecimal bigDecimal = new BigDecimal("1234.24564");
String toPlainStringResult = bigDecimal.toPlainString();// 结果为 "1234.24564"

PS:

toString和toPlainString的区别:

相同点:都是将BigDecimal类型转为String类型。

不同点:

toString方法,如果数值太大或太小,以至于其标准字符串表示形式不适合显示,可能会使用科学计数法表示。

toPlainString方法,与数值的大小无关,都会转换为一个不含任何科学计数法表示的字符串。也就是说,它会返回一个纯粹的十进制表示,不包含"E"或"e"这样的指数符号

示例:

//toString方法
BigDecimal bd = new BigDecimal("1.2345678901234567890e+20");  
System.out.println(bd.toString()); // 输出:1.2345678901234568E+20

//toPlainString方法
BigDecimal bd = new BigDecimal("12345678901234567890.12345678901234567890");  
System.out.println(bd.toPlainString()); // 输出:12345678901234567890.12345678901234567890

stripTrailingZeros()

说明:除去BigDecimal类型小数点后的所有零之后的值。

示例:

BigDecimal bg = new BigDecimal("123.4500");
BigDecimal bg1 = bg.stripTrailingZeros(); // 结果为 123.45

PS:stripTrailingZeros()方法不会改变BigDecimal对象的值,它只是返回一个新的BigDecimal对象。

使用场景中基本上都是先使用stripTrailingZeros去掉小数点之后的零,再通过toPlainString方法将BigDecimal类型转为字符串类型。


BigDecimal常量

BigDecimal为什么会提供这些常量?

主要是为了提供方便、可读性强且类型安全的方式来表示特定的值或行为。

具体体现有:

  • 特定的数值(BigDecimal.ZERO、BigDecimal.ONE、BigDecimal.TEN等)使用这些常量而不是直接使用字面量或变量,可以确保在代码中使用的值始终是预期的 Bigecimal 类型,防止类型错误等问题。
  • 舍入模式(ROUND_UP、ROUND_DOWN、ROUND_HALF_UP等)使用常量可以使这些操作更加直观和简洁。

特定数值的常量

BigDecimal.ZERO

说明:通常用作初始化或比较,表示数值0。

返回值/效果:一个表示数值0的BigDecimal对象。

BigDecimal.ONE

说明: 表示数值1,用于初始化、计算或比较。

返回值/效果:一个表示数值1的BigDecimal对象。

BigDecimal.TEN

说明: 表示数值10,常用于初始化、乘法或除法操作。

返回值/效果: 一个表示数值10的BigDecimal对象。

示例:

// 使用常量表示特定数值  
BigDecimal zero = BigDecimal.ZERO;  
BigDecimal one = BigDecimal.ONE;  
BigDecimal ten = BigDecimal.TEN;  
  
System.out.println(zero); // 输出: 0  
System.out.println(one);  // 输出: 1  
System.out.println(ten);  // 输出: 10 

舍入模式常量

这些常量通常用作setScale、round等方法的参数,来指定数值舍入的方式。

BigDecimal.ROUND_UP

说明:舍入时,总是向远离零的方向舍入。

返回值/效果:根据舍入规则调整后的BigDecimal对象。

BigDecimal.ROUND_DOWN

说明:舍入时,总是向零的方向舍入。

返回值/效果:根据舍入规则调整后的BigDecimal对象。

BigDecimal.ROUND_CEILING

说明:舍入时,总是向正无穷大的方向舍入。

返回值/效果:根据舍入规则调整后的BigDecimal对象。

BigDecimal.ROUND_FLOOR

说明:舍入时,总是向负无穷大的方向舍入。

返回值/效果: 根据舍入规则调整后的BigDecimal对象。

BigDecimal.ROUND_HALF_UP

说明:标准的四舍五入,如果舍弃部分 >= 0.5,则结果向远离零的方向舍入;否则,结果向零的方向舍入。

返回值/效果:根据四舍五入规则调整后的BigDecimal对象。

BigDecimal.ROUND_HALF_DOWN

说明:类似于ROUND_HALF_UP,但只有当舍弃部分 > 0.5时,结果才向远离零的方向舍入。

返回值/效果:根据舍入规则调整后的BigDecimal对象。

BigDecimal.ROUND_HALF_EVEN

说明:银行家舍入法,尝试向最接近的偶数舍入。如果舍弃部分等于0.5,则结果向使舍入后的值成为偶数的方向舍入。

返回值/效果:根据银行家舍入规则调整后的BigDecimal对象。

示例:

// 使用舍入模式常量  
BigDecimal value = new BigDecimal("10.75");  
BigDecimal rounded = value.setScale(2, RoundingMode.ROUND_HALF_UP);  
System.out.println(rounded); // 输出: 10.75,因为10.75四舍五入到两位小数仍然是10.75  
  
BigDecimal value2 = new BigDecimal("10.76");  
BigDecimal rounded2 = value2.setScale(2, RoundingMode.ROUND_HALF_UP);  
System.out.println(rounded2); // 输出: 10.76,因为10.76四舍五入到两位小数是10.76

PS:虽然BigDecimal类仍然包含这些舍入模式的常量,但推荐使用RoundingMode枚举,因为它提供了更好的类型安全。(舍入模式在功能上是相同的)

  • 33
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值