BigDecimal 简单使用

article/2025/10/1 6:01:59

目录

为什么使用BigDecimal

解决方案

构造方法

类型转换

double 转 BigDecimal

BigDecimal 转 String

BigDecimal 转 double/int/long等

加减乘除取余

divide

舍入模式

比较大小

格式化(DecimalFormat)

小结


为什么使用BigDecimal

  • 1.float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果

  • 2.作为移动端,经常调用后端接口,返回参数类型由后端决定。当我们使用double去接收并使用可能产生以下问题。

    public void dfFormat() {double number =1000000000000.0;//变成了科学计数法log("number直接打印->"+number);log("numberString.valueOf->"+String.valueOf(number));}

输出结果

number直接打印->1.0E12,这里直接变成了科学计数法。

numberString.valueOf->1.0E12,转String也是科学计数法。

解决方案

  • 1、如果仅展示不需要后续做处理(保留小数位、加减乘除等),可以让后端返回String类型。

  • 2、使用BigDecimal

    • 1.直接使用BigDecimal替代double接收数据。

    • 2.将double转成BigDecimal。

    public void dfFormat() {double number =1000000000000.0;//toPlainStringlog("numberDecimal-> "+BigDecimal.valueOf(number).toPlainString());}

输出结果

numberDecimal-> 1000000000000,从结果可以看出,数据显示正常了。

double转BigDecimal,使用的是BigDecimal.valueOf(number) ,而不是 new BigDecimal(number)

BigDecimal转成String,使用的是toPlainString() ,而不是toString()

构造方法

BigDecimal提供的比较常用的是下面几种方法:

  • 1.public BigDecimal(String val):将 String 表示形式转换成 BigDecimal(推荐使用)

  • 2.public BigDecimal(int val):将 int 表示形式转换成 BigDecimal

  • 3.public BigDecimal(double val):将 double 表示形式转换为 BigDecimal(不推荐使用)

    public void dfFormat() {BigDecimal a = new BigDecimal("10");BigDecimal b = new BigDecimal(5);BigDecimal k = new BigDecimal(-16.0034);}

输出结果

 a-> 10b-> 5k-> -16.00339999999999918145476840436458587646484375

原因:float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该用于要求精确结果的场合。

类型转换

注意:double转BigDecimal使用new BigDecimal()的方式会造成精度丢失。怎么解决?看下面的类型转换。

double 转 BigDecimal

精度丢失解决方案:

  • 1:new BigDecimal(String.valueOf(number2));

  • 2:BigDecimal.valueOf(number2);

    public void dfFormat() {double number2 =-16.0034;log("number2直接打印->"+number2);//double转BigDecimal导致丢失精度log("number2Decimal-> "+new BigDecimal(number2).toPlainString());//精度丢失解决方案:log("精度丢失String.valueOf-> "+new BigDecimal(String.valueOf(number2)).toPlainString());log("精度丢失BigDecimal.valueOf-> "+BigDecimal.valueOf(number2).toPlainString());}

输出结果

精度丢失String.valueOf-> -16.0034
精度丢失BigDecimal.valueOf-> -16.0034

BigDecimal 转 String

    public void dfFormat() {double number =1000000000000.0;//toString和toPlainStringlog("toString-> "+new BigDecimal(String.valueOf(number)).toString());log("toString-> "+BigDecimal.valueOf(number).toString());log("toPlainString-> "+ new BigDecimal(String.valueOf(number)).toPlainString());log("toPlainString-> "+BigDecimal.valueOf(number).toPlainString());

两种方式对比toString和toPlainString的区别。

输出结果

toString-> 1.0E+12
toString-> 1.0E+12
toPlainString-> 1000000000000
toPlainString-> 1000000000000

注意:很多人肯定习惯使用toString()了,但在BigDecimal这里就需要注意了,要使用toPlainString()。

BigDecimal 转 double/int/long等

        //如:BigDecimal转doubleBigDecimal b = new BigDecimal(5);//doubleValue-> 5.0log("doubleValue-> "+b.doubleValue());

加减乘除取余

BigDecimal 提供的方法:

    public BigDecimal add(BigDecimal augend) {}//加public BigDecimal subtract(BigDecimal subtrahend) {}//减public BigDecimal multiply(BigDecimal multiplicand) {}//乘public BigDecimal divide(BigDecimal divisor) {}//除(不推荐使用)public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {}//除(推荐使用)public BigDecimal[] divideAndRemainder(BigDecimal divisor) {}//取余
        //加减乘除BigDecimal a = new BigDecimal("10");BigDecimal b = new BigDecimal(5);log("10 + 5-> "+a.add(b).toPlainString());log("10 - 5-> "+a.subtract(b).toPlainString());log("10 * 5-> "+a.multiply(b).toPlainString());log("10 / 5-> "+a.divide(b).toPlainString());BigDecimal e = BigDecimal.valueOf(5.34178);BigDecimal f = BigDecimal.valueOf(3.12456);//e.divide(f)直接报错
//        e("e / f-> "+e.divide(f).toPlainString());log("e / f-> "+e.divide(f,3,BigDecimal.ROUND_HALF_UP).toPlainString());//取余BigDecimal []h = e.divideAndRemainder(f);log("e / f 取余 整-> "+h[0]+"余->"+h[1]);BigDecimal []j = a.divideAndRemainder(b);log("10 / 5 取余 整-> "+j[0]+"余->"+j[1]);

输出结果

10 + 5-> 15
10 - 5-> 5
10 * 5-> 50
10 / 5-> 2
e / f-> 1.710
e / f 取余 整-> 1余->2.21722
10 / 5 取余 整-> 2余->0

注意:

  • 1.为什么不推荐使用divide(BigDecimal divisor)?当 BigDecimal除法可能出现不能整除的情况,就会发送运行时异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。

  • 2.跟String一样, BigDecimal页是不可变的,在进行每一步运算时,都会产生一个新的对象。

divide

e.divide(f,3,BigDecimal.ROUND_HALF_UP)

参数解释:

  • divisor:除数

  • scale:表示小数点保留位数

  • roundingMode:表示舍入模式

舍入模式

我们一般舍入模式采取的是ROUND_HALF_UP,默认的也是ROUND_HALF_UP。

  • ROUND_CEILING //向正无穷方向舍入

  • ROUND_UP //不管保留数字后面是大是小 (0 除外) 都会进1

  • ROUND_DOWN //舍去制,截断操作,后面所有数字直接去除。结果会向原点方向对齐

  • ROUND_FLOOR //向负无穷方向舍入

  • ROUND_HALF_EVEN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN

  • ROUND_HALF_UP //四舍五入:向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 3.15保留一位小数结果为3.2

  • ROUND_HALF_DOWN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如3.15 保留一位小数结果为3.1

  • ROUND_UNNECESSARY //计算结果是精确的,不需要舍入模式

比较大小

        //比较大小BigDecimal u = new BigDecimal("1");//BigDecimal.ZERO==0;if(u.compareTo(BigDecimal.ZERO)==-1){log("u 小于 0");}if(u.compareTo(BigDecimal.ZERO)==0){log("u 等于 0");}if(u.compareTo(BigDecimal.ZERO)==1){log("u 大于 0");}BigDecimal um = new BigDecimal("-1");BigDecimal uzero = new BigDecimal("0");if(um.compareTo(BigDecimal.ZERO)==-1){log("um 小于 0");}if(uzero.compareTo(BigDecimal.ZERO)==0){log("uzero 等于 0");}

输出结果

 u 大于 0um 小于 0uzero 等于 0

BigDecimal 提供了三个常量分别为0,1,10。使用方法如上面的BigDecimal.ZERO(0)。

    //0public static final BigDecimal ZERO = new BigDecimal(0, 0);//1public static final BigDecimal ONE = new BigDecimal(1, 0);//10public static final BigDecimal TEN = new BigDecimal(10, 0);

格式化(DecimalFormat)

比如我们常用的保留小数位、补零、去零。

        DecimalFormat df2 = new DecimalFormat("######0.##");DecimalFormat df3 = new DecimalFormat("######0.###");//保留2位小数,不补零log(df2.format(3.1415927));//3.14log(df2.format(3.1));//3.14//保留3位小数,不补零log(df3.format(3.1415927));//3.142,默认四舍五入log(df2.format(3.1));//3.14DecimalFormat df22 = new DecimalFormat("######0.00");DecimalFormat df32 = new DecimalFormat("######0.000");//保留2位小数,补零log(df22.format(3.2));//3.20//保留3位小数,补零log(df32.format(3.2));//3.200//去掉BigDecimal后无用的零BigDecimal g = new BigDecimal("0.1000");log(g.stripTrailingZeros().toPlainString());//0.1double pi = 3.1415927;System.out.print(pi);//取一位整数log(new DecimalFormat("0").format(pi));//3//取一位整数和两位小数log(new DecimalFormat("0.00").format(pi));//3.14//取两位整数和三位小数,整数不足部分以0填补。log(new DecimalFormat("00.000").format(pi));// 03.142//取所有整数部分log(new DecimalFormat("#").format(pi));//3//以百分比方式计数,并取两位小数log(new DecimalFormat("#.##%").format(pi));//314.16%long c = 299792458;//光速//每三位以逗号进行分隔。log(new DecimalFormat(",###").format(c)); //299,792,458// 将格式嵌入文本光速大小为每秒299,792,458米。log(new DecimalFormat("光速大小为每秒,###米。").format(c)); 

小结

  • 1.double解决不了的时候使用BigDecimal。

  • 2.尽量使用参数类型为String的构造函数。

  • 3.double转BigDecimal时,不要使用new BigDecimal()。

  • 4.BigDecimal转String时,使用toPlainString()而不是toString()。

  • 5.除法运算,需要考虑除不尽的情况。


http://chatgpt.dhexx.cn/article/LM6PL2pt.shtml

相关文章

BigDecimal用法

文章目录 1、创建一个BigDecimal对象1.1、常用构造函数1.1、常用计算方法 2、BigDecimal很方便的几个用法2.1、用BigDecimal去除小数点后多余的0:stripTrailingZeros()2.2、BigDecimal的原值和科学计数值2.3、用BigDecimal比较大小:compareTo()2.4、BigD…

mysql bigdecimal查询_mysql bigdecimal

java学习:Java中的其它类 568x573 - 55KB - JPEG Java中BigDecimal类你了解多少?! 720x480 - 30KB - JPEG TypeHandlers 640x396 - 25KB - JPEG BigDecimal equals方法可能不相等 678x260 - 9KB - JPEG

BigDecimal 详解

一,BigDecimal的简介 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。 双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学…

BigDecimal加减乘除计算

BigDecimal的运算——加减乘除 首先是bigdecimal的初始化 这里对比了两种形式,第一种直接value写数字的值,第二种用string来表示 我们对其进行加减乘除绝对值的运算,其实就是Bigdecimal的类的一些调用 BigDecimal num1 new BigDecimal(0.005);BigDecim…

java 中 BigDecimal 详解

首先,学习一个东西,我们都必须要带着问题去学,这边我分为 【为什么?】【是什么?】【怎么用?】 【为什么要用BigDecimal?】 首先,我们先看一下,下面这个现象 那为什么会…

Java —— JDBC关闭Statement后是否还需要关闭ResultSet?

一、问题描述 下面的代码使用了try-with-resource语法,会自动关闭Connection和Statement,是否还需要关闭ResultSet? Statement关闭后ResultSet会被回收么? 二、JDBC规范 JDBC规范4.3中有对Statement关闭后是否需要关闭ResultSet进行说明。…

ResultSet(结果集)、Statement

ResultSet 基本介绍: 1.表示数据库结果集的数据表,通常通过执行查询数据库的语句生成 2.ResultSet对象保持一个光标指向其当前的数据行,光标最初在第一行之前 3.next()方法是将光标移动到下一行,并且由于在ResultSet对象中没有…

【JDBC】------ResultSet(结果集)和常见异常

分享第二十条励志语句 宁可自信,也不要盲目悲观。因为自信是一种力量,即使你的自信有些盲目,也无关大局,你可以在实践中调整心态,找到自己的恰当的位置。如果盲目自卑,你就必然失去一切。 目录 分享第二十…

JDBC的ResultSet

一、ResultSet[结果集] 1.表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。 2.ResultSet对象保持一个光标指向其当前的数据行,最开始光标在第一行。 3.next方法将光标移动到下一行,由于在ResultSet对象中没有更多行时返回fal…

Java中,ResultSet 的用法

•在Java中,获得ResultSet的总行数的方法有以下几种。 第一种:利用ResultSet的getRow方法来获得ResultSet的总行数 Java代码 Statement stmt con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); ResultSet r…

ResultSet结果集的使用

一、ResultSet结果集的简介 查询数据库时,返回的是一个二维的结果集,我们需要用到ResultSet来遍历结果集,获取每一行的数据。 二、使用ResultSet遍历查询结果 boolean next() 将光标从当前位置向前移一行。 String  getString(int column…

ResultSet用法集锦

ResultSet用法集锦 添加链接描述 结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等.结果集读取数据…

ResultSet的介绍与使用

相关文章 jdbc连接以及出现的异常处理Jdbc工具类ResultSet的介绍与使用jdbc中的sql注入PreparedStatement的介绍与解决sql注入jdbc管理事务 ResultSet ResultSet是我们使用jdbc连接时,查询的一个返回结果集,ResultSet resultSet stmt.executeQuery(sql),下面就使用…

JDBC之ResultSet接口

ResultSet介绍 对数据库的查询操作,一般需要返回查询结果。在程序中,JDBC为我们提供了ResultSet接口来专门处理查询结果集。 由于ResultSet是JDBC的一个接口,先来简单了解一下JDBC: JDBC:Java Database Connection&am…

android studio BindService

一.输入: 1.全部代码: 主界面代码: public class BindServiceActivity extends AppCompatActivity implements View.OnClickListener {private static final String TAG "BindServiceActivity";private Button mBtBindService;…

Service中bindService

最近有用到Activity需要不断的从Service中获取数据,第一个想法肯定就是通过bind回调机制了,有几点概念模糊特此记录下: 单独使用bindService(),unbindService()会经历:->onCreate()->onBind()->Service runn…

bindService不调用onServiceConnected的问题

bindService不调用onServiceConnected的问题 昨天做一个项目时,Activity需要bindService获取到service实例与service进行交互,创建好service如下(例): class MyService{private IBinder mBinder new MyServicerBind…

bind服务

一、域名 www.baidu.com www.baidu.com. (.)根域 (com)一级域名 (baidu)二级域名 二、DNS解析记录分类 A记录、CNAME、MX记录、NS记录 1、A记录 通过域名直接查询到IP 例如&…

bindService启动流程

通过bindService启动的Service,会执行Service的onCreate、onBind、onUnbind、onDestroy方法,可以通过onBind方法返回的Binder对象和调用端进行通信,并且Service的生命周期和调用端同步。 如下是启动bindService的代码 var stu: Student? null val con…

AIDL报错,bindService一直连接不上、不起作用。

先说问题,最近用aidl,发现bindService根本就不走,不知道咋回事,明明写的没有任何毛病啊? //aidl绑定private void bind() {Intent intent new Intent();String pkg "com.example.mzz_service";//需要调用…