BigDecimal类
目录为什么会设计该类Float和Double类为什么会精度不够的情况是什么特点精度相关问题常用方法add()subtract()multiply()divide()compareTo()setSCale()doubleValue()、floatValue()、longValue()、intValue()等abs()negate()toString()toPlainString()stripTrailingZeros()BigDecimal常量BigDecimal为什么会提供这些常量特定数值的常量BigDecimal.ZEROBigDecimal.ONEBigDecimal.TEN舍入模式常量ROUND_UPROUND_DOWNROUND_CEILINGROUND_FLOORROUND_HALF_UPROUND_HALF_DOWNROUND_HALF_EVEN为什么会设计该类主要是为了解决 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.0subtract()说明从当前 BigDecimal 对象中减去另一个 BigDecimal 对象。示例BigDecimal bd1 new BigDecimal(10.0); BigDecimal bd2 new BigDecimal(5.0); BigDecimal difference bd1.subtract(bd2); // 结果为 5.0multiply()说明将当前 BigDecimal 对象与另一个 BigDecimal 对象相乘。例子BigDecimal bd1 new BigDecimal(10.0); BigDecimal bd2 new BigDecimal(2.0); BigDecimal product bd1.multiply(bd2); // 结果为 20.0divide()说明将当前 BigDecimal 对象除以另一个 BigDecimal 对象并指定结果的小数位数和舍入模式。示例BigDecimal bd1 new BigDecimal(10.0); BigDecimal bd2 new BigDecimal(3.0); BigDecimal quotient bd1.divide(bd2, 2, RoundingMode.HALF_UP); // 结果为 3.33compareTo()说明比较当前 BigDecimal 对象与另一个 Bigecimal 对象的大小。返回-1、0或1 分别表示小于、等于或大于。返回值说明如果这个BigDecimal小于参数val则返回一个负整数通常是-1。如果这个BigDecimal等于参数val则返回零0。如果这个BigDecimal大于参数val则返回一个正整数通常是1。示例BigDecimal bd1 new BigDecimal(10.0); BigDecimal bd2 new BigDecimal(10.0); BigDecimal bd3 new BigDecimal(20.0); int result bd1.compareTo(bd2); // 结果为 0因为 bd1 小于 bd2 int result bd1.compareTo(bd3); // 结果为 -1因为 bd1 小于 bd3 int result bd3.compareTo(bd2); // 结果为 1因为 bd3 大于 bd2setSCale()说明设置BigDecimal对象的小数位数并指定舍入模式。示例BigDecimal bd new BigDecimal(123.456789); BigDecimal rounded bd.setScale(2, RoundingMode.HALF_UP); // 结果为 123.46doubleValue()、floatValue()、longValue()、intValue()等说明将Bigecimal转换为其他数值类型示例BigDecimal bd new BigDecimal(123); double dblValue bd.doubleValue(); // 结果为 123.0 int intValue bd.intValue(); // 结果为 123abs()说明返回当前BigDecimal对象的绝对值。示例BigDecimal bd new BigDecimal(-10.0); BigDecimal absValue bd.abs(); // 结果为 10.0negate()说明返回当前BigDecimal数值的相反数取反。示例BigDecimal bd new BigDecimal(123.45); BigDecimal negateValue bd.negate(); // 结果为 -123.45 BigDecimal bd1 new BigDecimal(-123.46); BigDecimal negateValue1 bd1.negate(); // 结果为 123.46toString()说明将BigDecimal转换为字符串String类型。示例BigDecimal bd new BigDecimal(123.456); String strValue bd.toString(); // 结果为 123.456toPlainString()说明将BigDecimal转换为字符串String类型。示例BigDecimal bigDecimal new BigDecimal(1234.24564); String toPlainStringResult bigDecimal.toPlainString();// 结果为 1234.24564PStoString和toPlainString的区别相同点都是将BigDecimal类型转为String类型。不同点toString方法如果数值太大或太小以至于其标准字符串表示形式不适合显示可能会使用科学计数法表示。toPlainString方法与数值的大小无关都会转换为一个不含任何科学计数法表示的字符串。也就是说它会返回一个纯粹的十进制表示不包含E或e这样的指数符号示例//toString方法 BigDecimal bd new BigDecimal(1.2345678901234567890e20); System.out.println(bd.toString()); // 输出1.2345678901234568E20 //toPlainString方法 BigDecimal bd new BigDecimal(12345678901234567890.12345678901234567890); System.out.println(bd.toPlainString()); // 输出12345678901234567890.12345678901234567890stripTrailingZeros()说明除去BigDecimal类型小数点后的所有零之后的值。示例BigDecimal bg new BigDecimal(123.4500); BigDecimal bg1 bg.stripTrailingZeros(); // 结果为 123.45PSstripTrailingZeros()方法不会改变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等方法的参数来指定数值舍入的方式。ROUND_UP说明舍入时总是向远离零的方向舍入。返回值/效果根据舍入规则调整后的BigDecimal对象。ROUND_DOWN说明舍入时总是向零的方向舍入。返回值/效果根据舍入规则调整后的BigDecimal对象。ROUND_CEILING说明舍入时总是向正无穷大的方向舍入。返回值/效果根据舍入规则调整后的BigDecimal对象。ROUND_FLOOR说明舍入时总是向负无穷大的方向舍入。返回值/效果 根据舍入规则调整后的BigDecimal对象。ROUND_HALF_UP说明标准的四舍五入如果舍弃部分 0.5则结果向远离零的方向舍入否则结果向零的方向舍入。返回值/效果根据四舍五入规则调整后的BigDecimal对象。ROUND_HALF_DOWN说明类似于ROUND_HALF_UP但只有当舍弃部分 0.5时结果才向远离零的方向舍入。返回值/效果根据舍入规则调整后的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.76PS虽然BigDecimal类仍然包含这些舍入模式的常量但推荐使用RoundingMode枚举因为它提供了更好的类型安全。舍入模式在功能上是相同的