2025年java后端实现加减乘除和比例计算

java后端实现加减乘除和比例计算java 后端实现加减乘除和比例计算 在 java math 包中提供了 API 类 BigDecimal 用来对超过 16 位有效位的数进行精确的运算 BigDecimal 所创建的是对象 所以不能使用 等算术运算符直接对其对象进行数学运算 首先需要了解 BigDecimal 一共有 4 种构造方法

大家好,我是讯享网,很高兴认识大家。

java后端实现加减乘除和比例计算

首先需要了解 BigDecimal 一共有4种构造方法:

 //创建一个具有参数所指定整数值的对象 BigDecimal(int) //创建一个具有参数所指定双精度值的对象 BigDecimal(double) //创建一个具有参数所指定整数值的对象 BigDecimal(long) //创建一个具有参数所指定以字符串表示的数值的对象 BigDecimal(String) //这里对比了两种形式,第一种直接value写数字的值,第二种用string来表示 BigDecimal num1 = new BigDecimal(0.005); BigDecimal num2 = new BigDecimal(); BigDecimal num3 = new BigDecimal(-); //尽量用字符串的形式初始化 BigDecimal num12 = new BigDecimal("0.005"); BigDecimal num22 = new BigDecimal(""); BigDecimal num32 = new BigDecimal("-"); 

讯享网

1、加减乘除

讯享网 //加法 add() BigDecimal result1 = num1.add(num2); BigDecimal result12 = num12.add(num22); //减法 subtract() BigDecimal result2 = num1.subtract(num2); BigDecimal result22 = num12.subtract(num22); //乘法 multiply() BigDecimal result3 = num1.multiply(num2); BigDecimal result32 = num12.multiply(num22); //绝对值 abs() BigDecimal result4 = num3.abs(); BigDecimal result42 = num32.abs(); //除法 divide() //num1、num12 除数, 20 精确小数位, BigDecimal.ROUND_HALF_UP 舍入模式 BigDecimal result5 = num2.divide(num1,20,BigDecimal.ROUND_HALF_UP); BigDecimal result52 = num22.divide(num12,20,BigDecimal.ROUND_HALF_UP); //去除末尾多余的0: new BigDecimal("100.000").stripTrailingZeros().toPlainString(); 

这里把result全部输出可以看到结果
这里出现了差异,这也是为什么初始化建议使用string的原因
在这里插入图片描述
讯享网
※ 注意:

1)System.out.println()中的数字默认是double类型的,double类型小数计算不精准。

2)使用BigDecimal类构造方法传入double类型时,计算的结果也是不精确的!

因为不是所有的浮点数都能够被精确的表示成一个double 类型值,有些浮点数值不能够被精确的表示成 double 类型值,因此它会被表示成与它最接近的 double 类型的值。必须改用传入String的构造方法。这一点在BigDecimal类的构造方法注释中有说明。

除法divide()参数使用

 //即为(BigDecimal divisor 除数, int scale 精确小数位, int roundingMode 舍入模式) Public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 

但是舍入模式有很多种 BigDecimal.ROUND_XXXX_XXX, 具体都是什么意思呢

八种舍入模式解释如下

1)ROUND_UP

舍入远离零的舍入模式。

在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。

注意,此舍入模式始终不会减少计算值的大小。

2)ROUND_DOWN

接近零的舍入模式。

在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。

注意,此舍入模式始终不会增加计算值的大小。

3)ROUND_CEILING

接近正无穷大的舍入模式。

如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;

如果为负,则舍入行为与 ROUND_DOWN 相同。

注意,此舍入模式始终不会减少计算值。

4)ROUND_FLOOR

接近负无穷大的舍入模式。

如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;

加粗样式如果为负,则舍入行为与 ROUND_UP 相同。

注意,此舍入模式始终不会增加计算值。

5)ROUND_HALF_UP

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。

如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。

注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。

6)ROUND_HALF_DOWN

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。

如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。

7)ROUND_HALF_EVEN

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;

如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。

注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。

此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。

如果前一位为奇数,则入位,否则舍去。

以下例子为保留小数点1位,那么这种舍入方式下的结果。

1.15>1.2 1.25>1.2

8)ROUND_UNNECESSARY

断言请求的操作具有精确的结果,因此不需要舍入。

如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。

举个例子:计算1÷3的结果(最后一种ROUND_UNNECESSARY在结果为无限小数的情况下会报错)
在这里插入图片描述
在这里插入图片描述

2、比较大小

讯享网 //前提为a、b均不能为null BigDecimal a = new BigDecimal("xx"); BigDecimal b = new BigDecimal("xx"); if(a.compareTo(b) == -1){ 
    System.out.println("a小于b"); } if(a.compareTo(b) == 0){ 
    System.out.println("a等于b"); } if(a.compareTo(b) == 1){ 
    System.out.println("a大于b"); } if(a.compareTo(b) > -1){ 
    System.out.println("a大于等于b"); } if(a.compareTo(b) < 1){ 
    System.out.println("a小于等于b"); } 

3、BigDecimal总结

在需要精确的小数计算时再使用BigDecimal,BigDecimal的性能比double和float差,在处理庞大,复杂的运算时尤为明显。故一般精度的计算没必要使用BigDecimal。尽量使用参数类型为String的构造函数。

BigDecimal都是不可变的(immutable)的, 在进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值。

工具类推荐

package com.vivo.ars.util; import java.math.BigDecimal; / * 用于高精确处理常用的数学运算 */ public class ArithmeticUtils { 
    //默认除法运算精度 private static final int DEF_DIV_SCALE = 10; / * 提供精确的加法运算 * * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1, double v2) { 
    BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } / * 提供精确的加法运算 * * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static BigDecimal add(String v1, String v2) { 
    BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.add(b2); } / * 提供精确的加法运算 * * @param v1 被加数 * @param v2 加数 * @param scale 保留scale 位小数 * @return 两个参数的和 */ public static String add(String v1, String v2, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } / * 提供精确的减法运算 * * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static double sub(double v1, double v2) { 
    BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } / * 提供精确的减法运算。 * * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static BigDecimal sub(String v1, String v2) { 
    BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.subtract(b2); } / * 提供精确的减法运算 * * @param v1 被减数 * @param v2 减数 * @param scale 保留scale 位小数 * @return 两个参数的差 */ public static String sub(String v1, String v2, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } / * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static double mul(double v1, double v2) { 
    BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } / * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static BigDecimal mul(String v1, String v2) { 
    BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.multiply(b2); } / * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @param scale 保留scale 位小数 * @return 两个参数的积 */ public static double mul(double v1, double v2, int scale) { 
    BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return round(b1.multiply(b2).doubleValue(), scale); } / * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @param scale 保留scale 位小数 * @return 两个参数的积 */ public static String mul(String v1, String v2, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } / * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 * 小数点以后10位,以后的数字四舍五入 * * @param v1 被除数 * @param v2 除数 * @return 两个参数的商 */ public static double div(double v1, double v2) { 
    return div(v1, v2, DEF_DIV_SCALE); } / * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入 * * @param v1 被除数 * @param v2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1, double v2, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } / * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入 * * @param v1 被除数 * @param v2 除数 * @param scale 表示需要精确到小数点以后几位 * @return 两个参数的商 */ public static String div(String v1, String v2, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v1); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString(); } / * 提供精确的小数位四舍五入处理 * * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } / * 提供精确的小数位四舍五入处理 * * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static String round(String v, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(v); return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } / * 取余数 * * @param v1 被除数 * @param v2 除数 * @param scale 小数点后保留几位 * @return 余数 */ public static String remainder(String v1, String v2, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } / * 取余数 BigDecimal * * @param v1 被除数 * @param v2 除数 * @param scale 小数点后保留几位 * @return 余数 */ public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) { 
    if (scale < 0) { 
    throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP); } / * 比较大小 * * @param v1 被比较数 * @param v2 比较数 * @return 如果v1 大于v2 则 返回true 否则false */ public static boolean compare(String v1, String v2) { 
    BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); int bj = b1.compareTo(b2); boolean res; if (bj > 0) res = true; else res = false; return res; } } 

好事定律:每件事最后都会是好事,如果不是好事,说明还没到最后。

小讯
上一篇 2025-04-11 21:11
下一篇 2025-03-11 22:34

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/57173.html