目录
doubleValue()、floatValue()、longValue()、intValue()等
为什么会设计该类?
主要是为了解决 Float 和 Double 类精度不够的问题而设计的。
Float和Double类为什么会精度不够的情况?
主要是由于它们基于IEEE 754标准使用二进制表示浮点数。这种表示方法虽然能覆盖很大范围的数值,但并不能精确地表示所有的十进制小数。
具体来说,二进制浮点数表示法存在以下问题:(这里放一下实际代码例子)
- 无法精确表示某些十进制小数:例如,0.1在二进制中是一个无限循环小数,因此无法用有限长度的二进制小数精确表示。当尝试将这样的十进制小数转换为二进制浮点数时,会产生舍入误差。
- 运算时的精度损失:在进行浮点数运算时,如加法、减法、乘法或除法,这些舍入误差可能会累积,导致结果的不精确。特别是在多次运算后,误差可能会变得显著。
- 表示范围的限制:虽然
Float
和Double
类型能表示很大范围的数值,但在某些极端情况下,超出其表示范围的数值会导致溢出或下溢,从而影响精度。
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"
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枚举,因为它提供了更好的类型安全。(舍入模式在功能上是相同的)