当前位置: 首页 > news >正文

BigDecimal的使用

BigDecimal的使用

1、BigDecimal常用构造函数

  • BigDecimal(int)

创建一个具有参数所指定整数值的对象

  • BigDecimal(double)

创建一个具有参数所指定双精度值的对象

  • BigDecimal(long)

创建一个具有参数所指定长整数值的对象

  • BigDecimal(String)

创建一个具有参数所指定以字符串表示的数值的对象

2、使用的一些坑

BigDecimal a = new BigDecimal(0.1);
System.out.println("a的值:"+a);
System.out.println("=====================");
BigDecimal b = new BigDecimal("0.1");
System.out.println("b的值:"+b);
a的值:0.1000000000000000055511151231257827021181583404541015625
=====================
b的值:0.1

image-20231120091429089

3、BigDecimal常用方法

1、常用方法
  • add(BigDecimal)

BigDecimal对象中的值相加,返回BigDecimal对象

  • ubtract(BigDecimal)

BigDecimal对象中的值相减,返回BigDecimal对象

  • multiply(BigDecimal)

BigDecimal对象中的值相乘,返回BigDecimal对象

  • divide(BigDecimal)

BigDecimal对象中的值相除,返回BigDecimal对象

  • toString()

将BigDecimal对象中的值转换成字符串

  • doubleValue()

将BigDecimal对象中的值转换成双精度数

  • floatValue()

将BigDecimal对象中的值转换成单精度数

  • longValue()

将BigDecimal对象中的值转换成长整数

  • intValue()

将BigDecimal对象中的值转换成整数

2、BigDecimal大小比较

java中对BigDecimal比较大小一般用的是bigdemical的compareTo方法

int a = bigdemical.compareTo(bigdemical2);

返回结果分析:

a = -1,表示bigdemical小于bigdemical2;
a = 0,表示bigdemical等于bigdemical2;
a = 1,表示bigdemical大于bigdemical2;

a大于等于b

new bigdemica(a).compareTo(new bigdemical(b)) >= 0
BigDecimal a =new BigDecimal("0.10");
BigDecimal b =new BigDecimal("0.1");
System.out.println(a == b);
System.out.println(a.equals(b));
System.out.println(a.compareTo(b));
false
false
0
3、BigDecimal格式化

由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。

以利用BigDecimal对货币和百分比格式化为例。首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。

NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用
NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用
percent.setMaximumFractionDigits(3); //百分比小数点最多3位BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额
BigDecimal interestRate = new BigDecimal("0.008"); //利率
BigDecimal interest = loanAmount.multiply(interestRate); //相乘System.out.println("贷款金额:\t" + currency.format(loanAmount));
System.out.println("利率:\t" + percent.format(interestRate));
System.out.println("利息:\t" + currency.format(interest));
贷款金额:	¥15,000.48
利率:	0.8%
利息:	¥120.00

BigDecimal格式化保留2为小数,不足则补0:

package com.xx.bigdecimal;import java.math.BigDecimal;
import java.text.DecimalFormat;/*** @Author: xueqimiao* @Date: 2023/11/20 09:09*/
public class BigDecimalTest {public static void main(String[] args) {System.out.println(formatToNumber(new BigDecimal("3.435")));System.out.println(formatToNumber(new BigDecimal(0)));System.out.println(formatToNumber(new BigDecimal("0.00")));System.out.println(formatToNumber(new BigDecimal("0.001")));System.out.println(formatToNumber(new BigDecimal("0.006")));System.out.println(formatToNumber(new BigDecimal("0.206")));}public static String formatToNumber(BigDecimal obj) {DecimalFormat df = new DecimalFormat("#0.00");return df.format(obj).toString();}
}
3.44
0.00
0.00
0.00
0.01
0.21
4、SpringBoot应用参数格式化
package com.xx.vo;import lombok.Data;import java.io.Serializable;
import java.math.BigDecimal;/*** @Author: xueqimiao* @Date: 2023/11/20 09:23*/
@Data
public class BigDecimalVO implements Serializable {private BigDecimal score;private BigDecimal scoreTo;
}
@GetMapping("/testDecimal")
public ResultData test(){BigDecimalVO bigDecimalVO = new BigDecimalVO();bigDecimalVO.setScore(new BigDecimal("0"));bigDecimalVO.setScoreTo(new BigDecimal("0"));return new ResultData(bigDecimalVO);}

@JsonSerialize 是 Java 中 Jackson 库提供的注解之一,用于定制对象在序列化(将对象转换为 JSON 字符串)过程中的行为。Jackson 是一个流行的 JSON 处理库,用于在 Java 对象和 JSON 数据之间进行转换。

当你在一个类或属性上使用 @JsonSerialize 注解时,你可以指定一个自定义的序列化器(serializer)。序列化器负责将对象转换为 JSON 格式,而不依赖于默认的方式。这可以用于处理一些特殊的需求,例如将对象以不同的方式序列化,或者在序列化过程中执行一些特殊的逻辑。

package com.xx.config;import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;/*** @Author: xueqimiao* @Date: 2023/11/20 09:29*/
public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {@Overridepublic void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {if (value != null) {gen.writeString(new DecimalFormat("#0.00").format(value));}}
}
@Data
public class BigDecimalVO implements Serializable {private BigDecimal score;@JsonSerialize(using = BigDecimalSerializer.class)private BigDecimal scoreTo;
}
5、BigDecimal常见异常
public static void main(String[] args) {BigDecimal bigDecimal = new BigDecimal(1);BigDecimal bigDecimal2 = new BigDecimal(3);System.out.println(bigDecimal.divide(bigDecimal2));
}
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.at java.base/java.math.BigDecimal.divide(BigDecimal.java:1780)at com.xx.bigdecimal.BigDecimalTest.main(BigDecimalTest.java:15)

通过BigDecimal的divide方法进行除法时不整除,出现无限循环小数时,就会抛异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

public static void main(String[] args) {BigDecimal bigDecimal = new BigDecimal(1);BigDecimal bigDecimal2 = new BigDecimal(3);BigDecimal result = bigDecimal.divide(bigDecimal2, 2, BigDecimal.ROUND_HALF_UP);System.out.println(result);
}

2表示2位小数,BigDecimal.ROUND_HALF_UP 是舍入模式,表示使用四舍五入。你可以根据你的需求选择不同的精度和舍入模式

4、BigDecimal工具类

package com.xx.util;import com.xx.utils.ValidationUtil;import java.math.BigDecimal;/*** @Author: xueqimiao* @Date: 2023/11/20 10:15*/
public class BigDecimalUtil {/*** 累加** @param values* @return*/public static BigDecimal add(BigDecimal... values) {if (ValidationUtil.isEmpty(values) || values.length == 0) {return new BigDecimal(0);}if (values.length == 1) {return values[0];} else {BigDecimal returnNum = ValidationUtil.isEmpty(values[0]) ? new BigDecimal(0) : values[0];for (int i = 1; i < values.length; i++) {if (ValidationUtil.isEmpty(values[i])) {continue;}BigDecimal b1 = returnNum;BigDecimal b2 = values[i];returnNum = b1.add(b2);}return returnNum;}}/*** 减法** @param param* @return*/public static BigDecimal subtract(BigDecimal... param) {if (ValidationUtil.isEmpty(param) || param.length == 0) {return new BigDecimal(0);}BigDecimal sumLess = param[0];//被减数for (int i = 1; i < param.length; i++) {BigDecimal bigDecimal = param[i] == null ? new BigDecimal(0) : param[i];sumLess = sumLess.subtract(bigDecimal);}return sumLess;}/*** 乘以** @param v1* @param v2* @return*/public static BigDecimal multiply(BigDecimal v1, BigDecimal v2) {if (ValidationUtil.isEmpty(v1) || ValidationUtil.isEmpty(v2)) {return new BigDecimal(0);}BigDecimal multiply = v1.multiply(v2);return multiply;}/*** 除以** @param v1* @param v2* @return*/public static BigDecimal divide(BigDecimal v1, BigDecimal v2) {if (ValidationUtil.isEmpty(v1) || ValidationUtil.isEmpty(v2) || v2.compareTo(new BigDecimal("0")) == 0) {return new BigDecimal(0);}return v1.divide(v2, 3, BigDecimal.ROUND_HALF_DOWN);}/*** 提供精确的减法运算** @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    乘数* @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();}/*** 提供(相对)精确的除法运算。当发生除不尽的情况时,由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;elseres = false;return res;}
}
http://www.xdnf.cn/news/1463473.html

相关文章:

  • 【AndroidStudio】官网下载免安装版,AndroidStudio压缩版的配置和使用
  • 华为网路设备学习-32(BGP协议 七)路由反射器与联邦
  • 中小企业数字化转型卡在哪?选对AI工具+用好企业微信,人力成本直降70%
  • SQLalachemy 错误 - Lost connection to MySQL server during query
  • 功能强大的多线程端口扫描工具,支持批量 IP 扫描、多种端口格式输入、扫描结果美化导出,适用于网络安全检测与端口监控场景
  • 基于SpringBoot的旅游管理系统的设计与实现(代码+数据库+LW)
  • 零基础直奔HCIE?先打好基础,后续才更轻松!
  • Redis 深度解析:数据结构、持久化与集群
  • 【Linux手册】动静态库:从原理到制作
  • mcp_clickhouse代码学习
  • 大彩串口屏-烧录与调试
  • 解决微信小程序开发初始化npm install包失败
  • uniapp阿里云验证码使用
  • Java观察者模式
  • 【Linux游记】基础指令篇
  • 关于CAN总线bus off 理论标准 vs 工程实践
  • XX汽集团数字化转型:全生命周期网络安全、数据合规与AI工业物联网融合实践
  • 数据可视化工具推荐:5款让图表制作轻松上手的神器
  • 23ai数据库通过SQLcl生成AWR报告
  • 【FastDDS】Layer Transport ( 01-overview )
  • 五年霸榜|悬镜安全持续引领《2025年中国网络安全市场全景图》DevSecOps开发安全赛道
  • Redis 发布订阅:社区的 “通知栏与分类订阅” 系统
  • Linux/UNIX系统编程手册笔记:DAEMON、编写安全的特权程序、能力、登录记账
  • 【QT 5.12.12 下载 Windows 版本】
  • Bing 搜索引擎检索语法
  • CodeQL(Mac)安装与测试(Visual Studio)简明指南
  • 解决IntelliJ IDEA 提交代码时无复选框问题
  • Node.js 做 Web 后端优势为什么这么大?
  • Spark面试题及详细答案100道(56-70)-- 性能优化
  • 逆天!影响因子0.1,竟然划分到中科院1区TOP?