BigDecimal使用总结

BigDecimal
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。

在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。

BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

第一:注意使用BigDecimal时要使用new BigDecimal("10.245755")或BigDecimal.valueOf(10.245755)形式,不能使用new BigDecimal(10.245755),否则会导致精度出现问题

BigDecimal b1 = new BigDecimal(10.245755);
BigDecimal b2 = BigDecimal.valueOf(10.245755);
BigDecimal b3 = new BigDecimal("10.245755");
System.out.println("b1: " + b1);
System.out.println("b2: " + b2);
System.out.println("b3: " + b3);


运行结果为:
b1: 10.2457550000000008338929546880535781383514404296875
b2: 10.245755
b3: 10.245755


备注:一定要注意切记不能使用new BigDecimal(10.245755)这种形式!!!

第二:BigDecimal常用加减乘除运算

BigDecimal b1 = BigDecimal.valueOf(10.245755);
BigDecimal b2 = new BigDecimal("10.24575");

//加减法的精度跟参与运算的两个值里面精度长的那一个精度保持一致
System.out.println("b1 + b2: " + b1.add(b2));
System.out.println("b1 - b2: " + b1.subtract(b2));
//乘法精度等于两个数精度的和
System.out.println("b1 x b2: " + b1.multiply(b2));
//除法,如果结果是无限循环小数,会报异常java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

//对结果做处理,保留特定位数小数
System.out.println("b1 / b2: " + b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP));


//注意,这是错误处理,这样仍然会存在无限循环
System.out.println("b1 / b2: " + b1.divide(b2).setScale(2, BigDecimal.ROUND_HALF_UP));
//此时需要对结果做处理,保留特定位数小数
System.out.println("b1 / b2: " + b1.divide(b2));


运行结果:
b1 + b2: 20.491505
b1 - b2: 0.000005
b1 x b2: 104.97544429125
b1 / b2: 1.00

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

第三、BigDecimal比较大小

BigDecimal b1 = BigDecimal.valueOf(10.245755);
BigDecimal b2 = new BigDecimal("10.245755");
BigDecimal b3 = new BigDecimal("11.245755");
BigDecimal b4 = new BigDecimal("9.245755");

//BigDecimal类型的比较需要用compareTo方法,==返回0,a<b返回-1,a>b返回1
System.out.println("b1 == b2: " + b1.compareTo(b2));
System.out.println("b1 < b3: " + b1.compareTo(b3));
System.out.println("b1 > b4: " + b1.compareTo(b4));


运行结果:
b1 == b2: 0
b1 < b3: -1
b1 > b4: 1

第四:BigDecimal取绝对值,去尾保留,四舍五入保留等运算

BigDecimal b1 = BigDecimal.valueOf(-10.245755);
BigDecimal b2 = new BigDecimal("10.245755");
BigDecimal b3 = new BigDecimal("10.545755");

//b1和b2的绝对值
System.out.println("b1绝对值: " + b1.abs());
System.out.println("b2绝对值: " + b2.abs());

//通过setScale()方法将小数点后的位数截断
//setScale()并将小数点后的位数设置为0,以截断小数点后的位数。ROUND_DOWN是舍位模式之一,它表示直接截断小数点后的位数,不进行四舍五入
System.out.println("b2小数点截断: " + b2.setScale(0, BigDecimal.ROUND_DOWN));
System.out.println("b3小数点截断: " + b3.setScale(0, BigDecimal.ROUND_DOWN));
System.out.println("b2小数点截断: " + b2.setScale(2, BigDecimal.ROUND_DOWN));
System.out.println("b3小数点截断: " + b3.setScale(2, BigDecimal.ROUND_DOWN));

//setScale()并将小数点后的位数设置为0,以截断小数点后的位数。ROUND_UP是舍位模式之一,它表示直接截断小数点后的位数,直接进1
System.out.println("b2小数点截断: " + b2.setScale(0, BigDecimal.ROUND_UP));
System.out.println("b3小数点截断: " + b3.setScale(0, BigDecimal.ROUND_UP));
System.out.println("b2小数点截断: " + b2.setScale(2, BigDecimal.ROUND_UP));
System.out.println("b3小数点截断: " + b3.setScale(2, BigDecimal.ROUND_UP));

//setScale()并将小数点后的位数设置为0,以截断小数点后的位数。ROUND_HALF_UP是舍位模式之一,它表示直接截断小数点后的位数,进行四舍五入
System.out.println("b2小数点截断: " + b2.setScale(0, BigDecimal.ROUND_HALF_UP));
System.out.println("b3小数点截断: " + b3.setScale(0, BigDecimal.ROUND_HALF_UP));
System.out.println("b2小数点截断: " + b2.setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println("b3小数点截断: " + b3.setScale(2, BigDecimal.ROUND_HALF_UP));

运行结果:
b1绝对值: 10.245755
b2绝对值: 10.245755
b2小数点截断: 10
b3小数点截断: 10
b2小数点截断: 10.24
b3小数点截断: 10.54
b2小数点截断: 11
b3小数点截断: 11
b2小数点截断: 10.25
b3小数点截断: 10.55
b2小数点截断: 10
b3小数点截断: 11
b2小数点截断: 10.25
b3小数点截断: 10.55

 

第五、BigDecimal类型转换

BigDecimal b1 = BigDecimal.valueOf(10.245755);
BigDecimal b2 = BigDecimal.valueOf(10.2457556545158512211222);

//BigDecimal类型转换
System.out.println("b1转int: " + b1.intValue());
System.out.println("b1转double: " + b1.doubleValue());
System.out.println("b1转long: " + b1.longValue());
System.out.println("b1转String: " + b1.toString());
System.out.println("b1转String: " + b1.toPlainString());
System.out.println("b1转String: " + b1.toEngineeringString());

System.out.println("====================================");
System.out.println("b2转int: " + b2.intValue());
System.out.println("b2转double: " + b2.doubleValue());
System.out.println("b2转long: " + b2.longValue());
System.out.println("b2转String: " + b2.toString());
System.out.println("b1转String: " + b2.toPlainString());
System.out.println("b1转String: " + b2.toEngineeringString());


运行结果:
b1转int: 10
b1转double: 10.245755
b1转long: 10
b1转String: 10.245755
b1转String: 10.245755
b1转String: 10.245755
====================================
b2转int: 10
b2转double: 10.24575565451585
b2转long: 10
b2转String: 10.24575565451585
b1转String: 10.24575565451585
b1转String: 10.24575565451585

补充案列如下:

注意,一般商业项目当中,BigDecimal用来做金额计算时,需要使用toPlainString()方法将BigDecimal转为String,这种方式不使用科学计数法,显示才是正常的数值

//案例一
         BigDecimal b1 = new BigDecimal("0.000000123").setScale(9);
     System.out.println(b1.toString());
      
     System.out.println(b1.scale());
     System.out.println(b1.unscaledValue());
	//输出结果为
     1.23E-7
     0.000000123
     9
     123

	//案例二
     BigDecimal b2 = new BigDecimal("0.000001234").setScale(9);
     System.out.println(b2.toString());
     System.out.println(b2.toPlainString());
     System.out.println(b2.scale());
     System.out.println(b2.unscaledValue());
	//输出结果为
     0.000001234
     0.000001234
     9
     1234

	//案例三
     BigDecimal b3 = new BigDecimal("0.123000000").setScale(9);
     System.out.println(b3.toString());
     System.out.println(b3.toPlainString());
     System.out.println(b3.scale());
     System.out.println(b3.unscaledValue());
	//输出结果为
     0.123000000
     0.123000000
     9
     123000000

	 //案例四
     BigDecimal b4 = new BigDecimal("123000000");
     System.out.println(b4.toString());
     System.out.println(b4.toPlainString());
     System.out.println(b4.scale());
     System.out.println(b4.unscaledValue());
	//输出结果为
     123000000
     123000000
     0
     123000000

	//案例五
	//Double d = 12345678d; Double d = 12345678.0; 效果一样
     Double d = (double) 12345678;
     BigDecimal b5 = BigDecimal.valueOf(d);
     System.out.println(d);
     System.out.println(b5.toString());
     System.out.println(b5.toPlainString());
     System.out.println(b5.scale());
     System.out.println(b5.unscaledValue());
	//输出结果为
     1.2345678E7
     12345678
     12345678
     0
     12345678

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/66613.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode-每日一题【剑指 Offer 06. 从尾到头打印链表】

题目 输入一个链表的头节点&#xff0c;从尾到头反过来返回每个节点的值&#xff08;用数组返回&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,3,2]输出&#xff1a;[2,3,1] 限制&#xff1a; 0 < 链表长度 < 10000 解题思路 1.题目要求我们从尾到头反过…

Python爬虫在电商数据挖掘中的应用

作为一名长期扎根在爬虫行业的专业的技术员&#xff0c;我今天要和大家分享一些有关Python爬虫在电商数据挖掘中的应用与案例分析。在如今数字化的时代&#xff0c;电商数据蕴含着丰富的信息&#xff0c;通过使用爬虫技术&#xff0c;我们可以轻松获取电商网站上的产品信息、用…

401 · 排序矩阵中的从小到大第k个数

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; 题解&#xff1a; 九章算法 - 帮助更多程序员找到好工作&#xff0c;硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 class Solution { public:/*** param matrix: a matrix of intege…

mysql再docker中运行,直接在实体机上运行mysql命令初始化数据库数据

背景 项目上我们使用docker安装mysql&#xff0c;项目启动的时候需要利用sql语句初始化数据。 直接在实体上是识别不到mysql命令的。 实现方式 实现方式1&#xff1a;在docker容器内部执行sql语句 1. 将sql文件上传到容器内 docker cp /root/1.sql d5:/home/ 说明&#…

【小梦C嘎嘎——启航篇】类和对象(中篇)

【小梦C嘎嘎——启航篇】类和对象&#xff08;中篇&#xff09;&#x1f60e; 前言&#x1f64c;类的6个默认成员函数构造函数析构函数拷贝构造函数拷贝构造函数的特性有哪些&#xff1f;既然编译器可以自动生成一个拷贝构造函数&#xff0c;为什么我们还要自己设计实现呢&…

外卖点餐小程序开源源码——支持扫码点餐

一套支持店内扫码点餐、外卖点餐配送于一体的餐饮系统&#xff0c;支持商家创建优惠券&#xff0c;支持商家自定义打印机功能&#xff0c;支持商家财务管理&#xff0c;支持商户菜品管理&#xff0c;支持菜品自定义分类&#xff0c;支持商家招募骑手入驻功能。系统基于thinkphp…

【Axure动态面板】利用动态面板实现树形菜单的制作

利用动态面板&#xff0c;简单制作高保真的树形菜单。 一、先看效果 https://1poppu.axshare.com 二、实现思路 1、菜单无非就是收缩和展开&#xff0c;动态面板有个非常好的属性&#xff1a;fit to content&#xff0c;这个属性的含义是&#xff1a;面板的大小可以根据内容多少…

HCIP的OSPF综合实验

一、实验要求 1、R4为ISP&#xff0c;其上只能配置IP地址: R4与其他所有直连设备间使用公有 2、R3—R5/6/7为MGRE环境&#xff0c;R3为中心站点 3、整个OSPF环境IP地址为172.16.0.0/16 4、所有设备均可访问R4的环回 5、减少LSA的更新量&#xff0c;加快收敛&#xff0c;保障更…

《HeadFirst设计模式(第二版)》第七章代码——外观模式

代码文件目录&#xff1a; Subsystem: Amplifier package Chapter7_AdapterAndFacadePattern.FacadePattern.Subsystem;/*** Author 竹心* Date 2023/8/8**///扬声器 public class Amplifier {int volume 0;//音量public void on(){System.out.println("The amplifier …

NodeJs执行Linux脚本

&#xff08;我们活着不能与草木同腐&#xff0c;不能醉生梦死&#xff0c;枉度人生&#xff0c;要有所作为。——方志敏&#xff09; 为什么需要使用NodeJs执行Linux脚本 linux的sh脚本命令编写复杂&#xff0c;在不熟悉linux交互式命令的情况下&#xff0c;使用高级编程语言…

【论文研读】MARLlib 的架构分析

【论文研读】MARLlib: A Scalable Multi-agent Reinforcement Learning Library 和尚念经 多智能体强化学习框架研究。 多智能体强化学习库。 多智能体强化学习算法实现。 多智能体强化学习环境的统一化&#xff0c;标准化。 多智能体强化学习算法解析。 多智能体强化学习 算法…

Android 面试重点之Framework (Handler篇)

近期在网上看到不少Android 开发分享的面试经验&#xff0c;我发现基本每个面经中多多少少都有Framework 底层原理的影子。它也是Android 开发中最重要的一个部分&#xff0c;面试官一般会通过 Framework底层中的一些逻辑原理由浅入深进行提问&#xff0c;来评估应聘者的真实水…

小型双轮差速底盘机器人实现红外跟随功能

1. 功能说明 本文示例将实现R023样机小型双轮差速底盘跟随人移动的功能。在小型双轮差速底盘前方按下图所示安装3个 近红外传感器&#xff0c;制作一个红外线发射源&#xff0c;实现当红外发射源在机器人的检测范围内任意放置或移动时&#xff0c;机器人能追踪该发射源。 2. 电…

Teams Room视频会议室方案

需求背景&#xff1a; 适合在40平米的会议室参加Teams视频会议&#xff0c;会议桌周围可以坐20人&#xff0c;要求&#xff1a; 1&#xff0c;操作简单&#xff0c;一键入会Teams Room&#xff1b; 2&#xff0c;任何人带上自己的笔记本电脑&#xff0c;可以分享电脑画面&#…

Linux CEF(Chromium Embedded Framework)源码下载编译详细记录

Linux CEF&#xff08;Chromium Embedded Framework&#xff09;源码下载编译 背景 由于CEF默认的二进制分发包不支持音视频播放&#xff0c;需要自行编译源码&#xff0c;将ffmpeg开关打开才能支持。这里介绍的是Linux平台下的CEF源码下载编译过程。 前置条件 下载的过程非…

搭建Repo服务器

1 安装repo 参考&#xff1a;清华大学开源软件镜像站:Git Repo 镜像使用帮助 2 创建manifest仓库 2.1 创建仓库 git init --bare manifest.git2.2 创建default.xml文件 default.xml文件内容&#xff1a; <?xml version"1.0" encoding"UTF-8" ?…

MySQL语法2

DQL语句介绍 DQL是数据查询语言&#xff0c;用来查询数据库中表的记录 DQL-基本查询语句 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVIMG 分组后条件列表 ORDER BY 排列字段列表 LIMIT 分页参数 讲解过程&#xff1a;基本查询、条件查询…

博客网站添加复制转载提醒弹窗Html代码

网站如果是完全禁止右键&#xff08;复制、另存为等&#xff09;操作&#xff0c;对用户来说体验感会降低&#xff0c;但是又不希望自己的原创内容直接被copy&#xff0c;今天飞飞和你们分享几行复制转载提醒弹窗Html代码。 效果展示&#xff1a; 复制以下代码&#xff0c;将其…

c语言每日一练(4)

五道选择题 1、有以下代码&#xff0c;程序的输出结果是( ) #include <stdio.h> int main() {int a 0, b 0;for (a 1, b 1; a < 100; a){if (b > 20) break;//1if (b % 3 1)//2{b b 3;continue;}b b-5;//3}printf("%d\n", a);return 0; } A.1…