福州网站制作设计,高端网站设计公司名单,代理网约车平台赚钱吗,营口规划建设局网站目录 简介类介绍案例分析总结BigDecimal类型的使用场景MySQL中存储BigDecimal类型数据补充#xff1a;BigDecimal类型使用时的注意事项BigDecimal类型的其他使用 简介 BigDecimal是Java中的一个类#xff0c;用于处理大数运算。它提供了精确的数值计算#xff0c;可以处理任… 目录 简介类介绍案例分析总结BigDecimal类型的使用场景MySQL中存储BigDecimal类型数据补充BigDecimal类型使用时的注意事项BigDecimal类型的其他使用 简介 BigDecimal是Java中的一个类用于处理大数运算。它提供了精确的数值计算可以处理任意位数的整数和小数避免了使用浮点数时可能出现的精度问题。 在普通的数值计算中使用Java的基本数据类型如int、double进行运算时有时会出现精度丢失的情况。例如计算0.1 0.2时使用double类型会得到0.30000000000000004而不是预期的0.3。 BigDecimal类提供了一系列的构造方法可以将基本数据类型、字符串等转换为BigDecimal对象。通过BigDecimal对象可以进行加减乘除、取模、取整、取精度等运算操作。在进行运算时BigDecimal会尽量保持精度避免精度丢失。 除了基本的数值运算BigDecimal还提供了比较、取绝对值、取反、取幂等方法以及将BigDecimal转换为其他数据类型的方法。
类介绍
看一下BigDecimal的类声明以及几个属性
public class BigDecimal extends Number implements ComparableBigDecimal {// 该BigDecimal的未缩放值private final BigInteger intVal;// 精度可以理解成小数点后的位数private final int scale;// BigDecimal中的十进制位数如果位数未知则为0(备用信息)private transient int precision;// Used to store the canonical string representation, if computed.// 这个我理解就是存实际的BigDecimal值private transient String stringCache;// 扩大成long型数值后的值private final transient long intCompact;
}案例分析
Test
public void testBigDecimal() {BigDecimal bigDecimal1 BigDecimal.valueOf(2.36);BigDecimal bigDecimal2 BigDecimal.valueOf(3.5);BigDecimal resDecimal bigDecimal1.add(bigDecimal2);System.out.println(resDecimal);
}在执行了BigDecimal.valueOf(2.36)后查看debug信息可以发现上述提到的几个属性被赋了值
进到add方法里面看看它是怎么计算的 // Arithmetic Operations/*** Returns a {code BigDecimal} whose value is {code (this * augend)}, and whose scale is {code max(this.scale(),* augend.scale())}.** param augend value to be added to this {code BigDecimal}.* return {code this augend}*/public BigDecimal add(BigDecimal augend) {if (this.intCompact ! INFLATED) {if ((augend.intCompact ! INFLATED)) {return add(this.intCompact, this.scale, augend.intCompact, augend.scale);} else {return add(this.intCompact, this.scale, augend.intVal, augend.scale);}} else {if ((augend.intCompact ! INFLATED)) {return add(augend.intCompact, augend.scale, this.intVal, this.scale);} else {return add(this.intVal, this.scale, augend.intVal, augend.scale);}}}结合传入的值来看 进入这个add方法来看 private static BigDecimal add(final long xs, int scale1, final long ys, int scale2) {long sdiff (long) scale1 - scale2;if (sdiff 0) {return add(xs, ys, scale1);} else if (sdiff 0) {int raise checkScale(xs,-sdiff);long scaledX longMultiplyPowerTen(xs, raise);if (scaledX ! INFLATED) {return add(scaledX, ys, scale2);} else {BigInteger bigsum bigMultiplyPowerTen(xs,raise).add(ys);return ((xs^ys)0) ? // same sign testnew BigDecimal(bigsum, INFLATED, scale2, 0): valueOf(bigsum, scale2, 0);}} else {int raise checkScale(ys,sdiff);long scaledY longMultiplyPowerTen(ys, raise);if (scaledY ! INFLATED) {return add(xs, scaledY, scale1);} else {BigInteger bigsum bigMultiplyPowerTen(ys,raise).add(xs);return ((xs^ys)0) ?new BigDecimal(bigsum, INFLATED, scale1, 0): valueOf(bigsum, scale1, 0);}}}这个例子中该方法传入的参数分别是xs236scale12ys35scale21
该方法首先计算scale1 - scale2根据差值走不同的计算逻辑这里求出来是1所以进入到最下面的else代码块这块是关键
首先17行校验了一下数值范围int raise checkScale(ys,sdiff); 18行将ys扩大了10的n次倍这里nraise1所以返回的scaledY350
接着就进入到20行的add方法 private static BigDecimal add(long xs, long ys, int scale){long sum add(xs, ys);if (sum!INFLATED)return BigDecimal.valueOf(sum, scale);return new BigDecimal(BigInteger.valueOf(xs).add(ys), scale);}这个方法很简单就是计算和然后返回BigDecimal对象
总结
所以可以得出结论BigDecimal在计算时实际会把数值扩大10的n次倍变成一个long型整数进行计算整数计算时自然可以实现精度不丢失。同时结合精度scale实现最终结果的计算。
BigDecimal类型的使用场景
BigDecimal类型主要用于精确计算特别是在需要处理大数或需要保留小数位数精确的场景中。以下是一些使用BigDecimal类型的常见场景 财务计算在金融或财务领域需要对金额、利率、汇率等进行精确计算和舍入避免由于浮点数运算带来的精度问题。 税务计算对于需要计算税额、税率等的场景BigDecimal类型可以确保计算结果的准确性并避免误差。 计量单位转换在需要进行单位转换的场景中BigDecimal可以提供精确的计算结果确保转换的准确性。 程序性能测试在进行性能测试时可能需要进行大量的计算操作使用BigDecimal类型可以避免浮点数运算带来的精度误差确保测试结果的准确性。 商业应用开发在开发商业应用时可能需要处理复杂的数值计算如利润率、销售额等使用BigDecimal类型可以确保计算结果的准确性避免精度丢失。
总之如果需要进行精确计算、保留小数位数或处理大数时在上述场景中使用BigDecimal类型是一个很好的选择。
MySQL中存储BigDecimal类型数据 在MySQL中可以使用DECIMAL数据类型来存储BigDecimal类型的数据。DECIMAL类型用于存储精确的数值支持指定精度和小数位数。 DECIMAL的语法DECIMAL(M, D) M表示总的位数D表示小数点后的位数。 例如要存储一个精确到小数点后两位的数字可以使用DECIMAL(6,2)类型。可以在创建表时指定DECIMAL类型的字段例如 CREATE TABLE example (id INT PRIMARY KEY,amount DECIMAL(10,2)
);在上述例子中amount字段的类型为DECIMAL总共有10位其中小数部分占2位。 可以通过INSERT语句插入BigDecimal值到DECIMAL字段中例如 INSERT INTO example (id, amount) VALUES (1, 1234.56);可以通过SELECT语句查询DECIMAL字段的值例如 SELECT amount FROM example WHERE id 1;注意需要根据实际情况来确定DECIMAL字段的合适的精度和小数位数以确保存储和计算的准确性。
补充BigDecimal类型使用时的注意事项
在使用BigDecimal类型时有一些注意事项需要注意 避免使用浮点数构造BigDecimal浮点数在计算机中以二进制表示可能会导致精度丢失。建议使用字符串或整数构造BigDecimal对象以确保精确性。 使用BigDecimal的字符串构造函数使用BigDecimal的字符串构造函数可以确保精确性例如new BigDecimal(“0.1”)。而使用new BigDecimal(0.1)可能会导致精度丢失。 设置精度和舍入模式可以使用setScale()方法设置BigDecimal的精度和舍入模式。精度指的是小数部分的位数舍入模式指的是如何处理小数位数超过精度的情况。 避免使用equals()方法比较BigDecimal由于BigDecimal是一个引用类型使用equals()方法比较BigDecimal对象时需要确保比较的精确度。推荐使用compareTo()方法来进行比较。 避免使用BigDecimal进行大量的运算由于BigDecimal对象是不可变的每次进行运算都会创建一个新的BigDecimal对象。如果需要进行大量的计算可以考虑使用BigDecimal的可变版本MutableBigDecimal。 注意处理除法运算的精度在进行除法运算时需要注意处理小数位数的精度和舍入模式。可以使用divide()方法指定精度和舍入模式。
总之使用BigDecimal时需要注意精度、舍入模式和数值的构造方式以确保计算的准确性和一致性。同时了解和使用BigDecimal的各种方法可以更好地处理数值计算和比较。
BigDecimal类型的其他使用
除了上述注意事项以下是一些BigDecimal类型的其他使用方法 加法和减法可以使用add()方法进行两个BigDecimal对象的相加使用subtract()方法进行相减。例如 BigDecimal num1 new BigDecimal(10.5);BigDecimal num2 new BigDecimal(5.3);BigDecimal sum num1.add(num2); // 结果为15.8BigDecimal difference num1.subtract(num2); // 结果为5.2乘法和除法可以使用multiply()方法进行乘法运算使用divide()方法进行除法运算。例如 BigDecimal num1 new BigDecimal(10.5);BigDecimal num2 new BigDecimal(2.5);BigDecimal product num1.multiply(num2); // 结果为26.25BigDecimal quotient num1.divide(num2); // 结果为4.2 取反操作可以使用negate()方法对BigDecimal对象进行取反操作。例如 BigDecimal num new BigDecimal(10.5);BigDecimal neg num.negate(); // 结果为-10.5取绝对值可以使用abs()方法获取BigDecimal对象的绝对值。例如 BigDecimal num new BigDecimal(-10.5);BigDecimal abs num.abs(); // 结果为10.5比较大小可以使用compareTo()方法对两个BigDecimal对象进行大小比较。例如 BigDecimal num1 new BigDecimal(10.5);BigDecimal num2 new BigDecimal(5.3);int result num1.compareTo(num2); // 结果为1num1大于num2