【Java基础系列】BigDecimal入门

一.基本介绍

1.什么是 BigDecimal?

BigDecimal 是 Java 中的一个类,用于表示任意精度的十进制数。它属于 java.math 包,并提供了高精度的浮点数运算。与基本数据类型的浮点数(如 floatdouble)不同,BigDecimal 可以表示精确的小数,并且不会出现舍入误差。

2.BigDecimal 特点?

主要的特点包括:

  1. 任意精度: BigDecimal 可以处理非常大或非常小的数字,而不会失去精度。这对于需要精确计算货币、税收等金融领域的数据非常重要。

  2. 不受二进制浮点数表示误差的影响: 由于二进制浮点数表示法的限制,基本数据类型的浮点数可能会导致舍入误差。BigDecimal 使用基于十进制的表示,避免了这种误差。

  3. 支持精确的算术运算: BigDecimal 提供了一系列的算术运算方法,如加法、减法、乘法和除法,这些运算可以保持高精度。

  4. 不可变性: BigDecimal 对象是不可变的,一旦创建,就不能被修改。这有助于确保线程安全性。

  5. 丰富的方法: BigDecimal 提供了许多用于比较、取整、取余等操作的方法。

3.使用简介

以下是一个简单的示例,演示如何使用 BigDecimal 进行精确计算:

import java.math.BigDecimal;public class BigDecimalExample {public static void main(String[] args) {BigDecimal num1 = new BigDecimal("10.5");BigDecimal num2 = new BigDecimal("2.3");// 加法BigDecimal sum = num1.add(num2);System.out.println("Sum: " + sum);// 减法BigDecimal difference = num1.subtract(num2);System.out.println("Difference: " + difference);// 乘法BigDecimal product = num1.multiply(num2);System.out.println("Product: " + product);// 除法,指定保留小数位数和舍入模式BigDecimal quotient = num1.divide(num2, 2, BigDecimal.ROUND_HALF_UP);System.out.println("Quotient: " + quotient);}
}

在这个示例中,BigDecimal 被用于执行精确的加法、减法、乘法和除法操作,并且可以通过指定保留小数位数和舍入模式来控制除法的结果。

二.使用简介

1.求和

求和

BigDecimal sum = Arrays.stream(bdArray).reduce(BigDecimal.ZERO, (p, q) -> p.add(q));
BigDecimal sum = list.stream().map(Person::getWeight).reduce(BigDecimal.ZERO, BigDecimal::add);

2.自定义求和

自定义求和

BigDecimal sum = map.values().stream().reduce(BigDecimal.ZERO, Utility::addWeight);
import java.math.BigDecimal;
public class Utility {public static BigDecimal addWeight(BigDecimal w1, BigDecimal w2) {return w1.add(w2);}
}

3.小数计算

小数

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
public class BigDecimalSumUsingList {public static void main(String[] args) {Person p1 = new Person("AAA", new BigDecimal("45.23"));Person p2 = new Person("BBB", new BigDecimal("55.43"));Person p3 = new Person("CCC", new BigDecimal("65.21"));Person p4 = new Person("DDD", new BigDecimal("35.73"));List<Person> list = Arrays.asList(p1, p2, p3, p4);BigDecimal sum = list.stream().map(Person::getWeight).reduce(BigDecimal.ZERO, BigDecimal::add);System.out.println(sum);sum = list.stream().map(p -> p.getWeight()).reduce(BigDecimal.ZERO, (b1, b2) -> b1.add(b2));System.out.println(sum);sum = list.stream().map(Person::getWeight).reduce(BigDecimal.ZERO, Utility::addWeight);System.out.println(sum);}
}

BigDecimal求和

BigDecimal sum = products.stream().map(Product::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

先相乘再累加:

 final BigDecimal mgmtPrmAmt = value.stream().map(product -> product.getMgmtPrmAmt().multiply(new BigDecimal(product.getSalQty()))).reduce(BigDecimal.ZERO, BigDecimal::add);

4.加减乘除

public BigDecimal add(BigDecimal value);  //加
public BigDecimal subtract(BigDecimal value);//减
public BigDecimal multiply(BigDecimal value);  //乘
public BigDecimal divide(BigDecimal value); //除

5.除法细节

RoundingMode类型:

  • ROUND_HALF_UP:根据保留数字后一位>=5 进行四舍五入
  • ROUND_UP:不管保留数字后面是大是小(0 除外)都会进 1
  • ROUND_DOWN:保留设置数字,后面所有直接去除
  • ROUND_HALF_DOWN:跟 ROUND_HALF_UP 差别仅在于 0.5 时会向下取整
  • ROUND_HALF_EVEN:取最近的偶数
  • ROUND_UNNECESSARY:不需要取整,如果存在小数位,就抛 ArithmeticException 异常
  • ROUND_CEILING:如果 BigDecimal 是正的,则做 ROUND_UP 操作;如果为负,则做 ROUND_DOWN 操作 (一句话:取附近较大的整数)
  • ROUND_FLOOR: 如果 BigDecimal 是正的,则做 ROUND_DOWN 操作;如果为负,则做 ROUND_UP 操作(一句话:取附近较小的整数)

BigDecimal 的 divide 方法是用于执行除法运算的,其语法如下:

#语法
public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode)#举例BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP);

其中,参数说明如下:

  • divisor:被除数,即要将当前 BigDecimal 对象除以的数。
  • scale:表示除法运算的结果要保留的小数位数。
  • roundingMode:表示舍入模式,用于在执行除法运算时确定如何舍入结果。

该方法返回一个 BigDecimal 对象,表示除法运算的结果。

import java.math.BigDecimal;
/*** @author : qinyingjie* @version : 2.2.0* @date : 2022/10/5 12:27*/
class Scratch {public static void main(String[] args) {//Java中BigDecimal取整方法BigDecimal bd = new BigDecimal("12.1");long l1 = bd.setScale(0, BigDecimal.ROUND_UP).longValue(); // 向上取整long l2 = bd.setScale(0, BigDecimal.ROUND_DOWN).longValue(); // 向下取整System.out.println(l1);System.out.println(l2);}
}

要将 a 除以 b,并将结果保留 2 位小数,可以使用如下代码:

BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");
BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP);
System.out.println(result);

在上述代码中,RoundingMode.HALF_UP 表示使用“四舍五入”方式将结果舍入到 2 位小数。

需要注意的是,如果除数为 0,则会抛出 ArithmeticException 异常。另外,如果计算结果超出了 BigDecimal 能表示的范围,则会抛出 ArithmeticException 异常。因此,在使用 BigDecimal 进行除法运算时,需要对这些异常进行适当的处理。

6.BigDecimal 与 0 比较

BigDecimal 如何判断是否大于 0、小于 0 和等于 0

if (number.compareTo(BigDecimal.ZERO) == 0) {System.out.println("BigDecimal对象等于0");
} else {System.out.println("BigDecimal对象不等于0");
}

7.保留 4 位小数

取最大值并保留 4 位小数,使用的方法是一个数除以 1 等于它本身

max.setTotalSalQtyStoreRate(new BigDecimal(result.stream().mapToDouble(item -> Objects.nonNull(item.getTotalSalQtyStoreRate()) ? item.getTotalSalQtyStoreRate().doubleValue() : 0).max().getAsDouble()).divide(new BigDecimal(1), 4, BigDecimal.ROUND_DOWN));

8.注意点

注意点:

  1. 小数先转为 String,不然会出现精度错误
  2. 比较用 compareTo,并且比较 0,用 BigDecimal.ZERO
  3. 除法时要确定保留小数的位数,不然有可能出现除不尽的情况
  4. 如果传入的字符串是一个非法的数值(null、字母、空),NumberFormatException 异常,
  5. 非空校验

BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

roundingMode 为四舍五入的规则模型,用常量 int 来表示

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Xilinx Zynq-7000系列FPGA多路视频处理:图像缩放+视频拼接显示,提供工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐FPGA图像处理方案FPGA图像缩放方案FPGA视频拼接叠加融合方案推荐 3、设计思路详解HLS 图像缩放介绍Video Mixer介绍 4、vivado工程介绍PL 端 FPGA 逻辑设计PS 端 SDK 软件设计 5、工程移植说明vivado版本不一致处理FPGA型号不一致处理其他…

【投稿优惠|稳定出版】2023年信息科学和大数据应用国际会议 (ICISBDA 2023)

2023年信息科学和大数据应用国际会议 (ICISBDA 2023&#xff09; 2023 International Conference on Information Science and Big Data Applications &#xff08;ICISBDA 2023&#xff09; 一、会议简介 &#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&…

Tensorflow的日志log记录

if OUTPUT_GRAPH:tf.summary.FileWriter("logs/", sess.graph)自动创建文件夹log

分享一个大学生免费的资源网站(含考研资源,竞赛四六级)

今天不小心从其他地方链接到的网站&#xff0c;里面包含考考研资料&#xff0c;四六级相关的资料&#xff0c;重点都是免费的&#xff0c;部分资料可能需要登录或者关注公众号才可见&#xff0c;&#xff0c;网站链接了CSDN 能跳转到CSND, 网站地址 :忠哥资源共享http://jian…

Pandas时序数据分析实践—基础(1)

目录 1. Pandas基本结构2. Pandas数据类型2.1. 类型概述2.1.1. 整数类型&#xff08;int&#xff09;&#xff1a;2.1.2. 浮点数类型&#xff08;float&#xff09;&#xff1a;2.1.3. 布尔类型&#xff08;bool&#xff09;&#xff1a;2.1.4. 字符串类型&#xff08;object&a…

Android 源码编译

一&#xff0c;虚拟机安装 ​ 1.1 进入https://cn.ubuntu.com/download中文官网下载iso镜像 1.2 这里我们下载Ubuntu 18.04 LTS 1.3虚拟VM机安装ubuntu系统&#xff0c;注意编译源码需要至少16G运行内存和400G磁盘空间&#xff0c;尽量设大点 二 配置编译环境 2.1 下载andr…

C++ day50 动态规划

题目1&#xff1a;123 买卖股票的最佳时机Ⅲ 题目链接&#xff1a;买卖股票的最佳时机Ⅲ 对题目的理解 prices[i]表示股票在第i天的价格&#xff0c;最多可以完成两笔交易&#xff0c;不能同时进行多笔交易 可以买卖一次&#xff0c;两次&#xff0c;也可以不买卖 动态规划…

C++-类和对象

目录 一.C语言和C的区别 二.类的引入 三.类的定义 1.类的定义 2.类的成员方法的两种定义方式&#xff1a; 3.类的成员变量的定义 四.类的访问限定符及封装 1.访问限定符 五.面向对象的三大特征 1.面向对象的三大特征分别是什么 2.封装 六.类的作用域 七.创建类对象 1.类…

Leetcode.330 按要求补齐数组

题目链接 Leetcode.330 按要求补齐数组 hard 题目描述 给定一个已排序的正整数数组 n u m s nums nums &#xff0c;和一个正整数 n n n 。从 [ 1 , n ] [1, n] [1,n] 区间内选取任意个数字补充到 n u m s nums nums 中&#xff0c;使得 [ 1 , n ] [1, n] [1,n] 区间内的…

CAN 一: CAN基础知识介绍

1、CAN介绍 1.1、什么是CAN? (1)CAN&#xff08;Controller Area Network:控制器局域网&#xff09;&#xff0c;是ISO国际标准化的串行通信协议。为满足汽车产业的“减少线束的数量”、“通过多个LAN&#xff0c;进行大量数据的高速通信”的需求。 (2)CAN总线的发展历史&a…

纯代码wordpress主题禁止复制粘贴文章内容的方法

很多站长&#xff0c;尤其是新手站长&#xff0c;通常都是内容的搬运工&#xff0c;那我们如何来扼制这些复制他人网站内容且不保留转载链接和署名这种不道德行为&#xff0c;那我们可以通过代码禁用在网站左右复制或是右健功能&#xff0c; 今天大挖就来给大家说说在wordpress…

【LeetCode】每日一题 2023_12_2 拼车(模拟/差分)

文章目录 刷题前唠嗑题目&#xff1a;拼车题目描述代码与解题思路学习大佬题解 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 题目&#xff1a;拼车 题目链接&#xff1a;1094. 拼车 题目描述 代码与解题思路 func carPooling(trips [][]int…

【Linux】第二十四站:模拟实现C语言文件标准库

文章目录 一、实现细节1.需要实现的函数2.fopen的实现3.fclose4.fwrite5.测试6.缓冲区的实现7.FILE中缓冲区的意义 二、完整代码 一、实现细节 1.需要实现的函数 #include "mystdio.h"int main() {_FILE* fp _fopen("test.txt","w");if(fp N…

超大规模集成电路设计----基本概念(二)

本文仅供学习&#xff0c;不作任何商业用途&#xff0c;严禁转载。绝大部分资料来自----数字集成电路——电路、系统与设计(第二版)及中国科学院段成华教授PPT 超大规模集成电路设计----基本概念&#xff08;二&#xff09; 简短的历史回顾(A Brief Historical Perspective)第…

观察者设计模式

package com.jmj.pattern.observer;/*抽象观察者类*/ public interface Observer {void update(String message);}package com.jmj.pattern.observer;/*** 抽象主题角色*/ public interface Subject {//添加观察者对象void attach(Observer observer);//删除订阅者void detach(…

LeetCode(51)简化路径【栈】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 简化路径 1.题目 给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 / 开头&#xff09;&#xff0c;请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中&#xff…

SmartSoftHelp8,FrameCode极速二次开发框架源码

1.winform outlook style UI C/S 极速开发框架 netframework 2.0 2.winform toolbar style UI C/S 极速开发框架 netframework 2.0 3.WPF toolbar style UI C/S 极速开发框架 netframework 4.0 4.Xadmin-UI jquery B/S 极速开发框架 5.Vue element UI B/S…

Presto基础学习--学习笔记

1&#xff0c;Presto背景 2011年&#xff0c;FaceBook的数据仓库存储在少量大型hadoop/hdfs集群&#xff0c;在这之前&#xff0c;FaceBook的科学家和分析师一直靠hive进行数据分析&#xff0c;但hive使用MR作为底层计算框架&#xff0c;是专为批处理设计的&#xff0c;但是随…

在vue3项目嵌套 导入老项目 jQuery项目,减少重复开发

背景&#xff1a; 公司管理平台项目一直是前辈用jQuery做的&#xff0c;为扩展根据自身的技术栈&#xff0c;将jQuery的老项目嵌套入vue3的框架&#xff0c;新功能用vue开发&#xff0c;旧的功能不动直接在vue3用iframe容器来展示 嵌套步骤 2种方式嵌套&#xff0c;一个是已…

微机原理——并行接口8255学习1

目录 并行接口特点 可编程并行接口芯片8255 8255端口地址 8255的三种工作方式 8255的两种命令&#xff08;方式命令和C端口命令&#xff09; 由用户扩展的并行接口8255的应用 声光报警器接口设计 步进电机控制接口设计 PA端口实现跑马灯 PB端口实现按键输入 并行接口特…