项目|金额场景计算BigDecimal使用简记

前言

        在实际项目开发中,我们经常会遇到一些金额计算,分摊等问题,通常我们都使用java.math.BigDecimal 来完成各种计算,避免使用浮点数float,double来计算金额,以免丢失精度,以下是博主部分使用场景和使用BigDecimal简记分享。。

案例1:统计各年龄段,用户存款:实现集合的所有金额相加,结果保留两位小数

        在平常项目中,我们经常会遇到查询某个集合,在集合下计算所有价钱的总和

 public static void main(String[] args) {//无论如何都会出现两位小数 java.math.BigDecimal.ROUND_HALF_UPList<User> userList = new ArrayStack();userList.add(new User().setAge(30).setMoney(new BigDecimal("145")).setUsername("dzx"));userList.add(new User().setAge(10).setMoney(new BigDecimal("143")).setUsername("dzx"));userList.add(new User().setAge(10).setMoney(new BigDecimal("144")).setUsername("dzx"));userList.add(new User().setAge(10).setMoney(new BigDecimal("142")).setUsername("dzx"));System.out.println(userList.stream().map(User::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add).setScale(2, ROUND_HALF_UP));}

        此处我们使用了stream的处理方式,更简洁的计算了总和,设置精度为2,和四舍五入,关于ROUND_HALF_UP的其他取值,可以参考java.math.BigDecimal.ROUND_HALF_UP静态方法里的取值,共有0-7序号的8种取值,经常使用ROUND_HALF_UP=4(四舍五入)、ROUND_HALF_DOWN=5(五舍六入)、ROUND_FLOOR=3(向下取整)、ROUND_CEILING=2(向上取整)

案例2:用户下单谋些商品,商品购买的支付金额不准确(包含了各种优惠),需要重新分摊计算每件商品金额,分摊的算法就是通过每件商品的支付金额占比,计算出具体每件商品的实付金额

        通常我们需要分摊,总会出现除不尽,或者精度问题,为此我们要保证总的数不能少,为了减少精度等问题,就要采用最后一件做减法的方式,这样就能保证最后分摊金额的准确性。以图中为例,用户下单购买了三件商品,订单总实付为100.1,支付为233,由于各种原因(平台各种优惠,银行满减,红包等活动)经常导致支付金额与实付金额不等,那么就要重新计算各商品的实付金额

在这里插入图片描述

ps:图中计算结果都为四舍五入,保留小数两位,计算器计算的结果,非程序

        三件商品,其中商品1:支付3,那么就需要计算她的实付金额,首先需要计算这件商品原支付金额的占比,再通过这个比例计算实付金额,商品2同理,到商品3则要采用最后一件做减法的方式,否则会造成总的实付金额会不等的情况。具体计算以商品1为例,实付金额为:3/233*100.1=1.29,按照这样的逻辑编写代码

     public static void main(String[] args) {//先除再乘BigDecimal result1 = new BigDecimal("3").divide(new BigDecimal("233"),2,ROUND_HALF_UP).multiply(new BigDecimal("100.1")).setScale(2,ROUND_HALF_UP);System.out.println("先除再乘,输出:"+result1);}
先除再乘,输出:1.00

        我们会发现程序实际计算结果,和程序计算结果有偏差,中间的偏差是哪里来的呢?答案是除法来的,我们在平常计算的时候,除以200的时候已经做了精度处理,因为我们不可能算的尽,因此我们的做法都是先乘后除,乘法为什么就不会有这个问题,因为乘法通常都是有限的数,非无穷的数,我们乘法可以避免进度丢失,因此我们实际计算的时候,需要调整计算公式,由3/233*100.1调整为3*100.1/200,具体代码如下:

      public static void main(String[] args) {//先乘再除BigDecimal result2 = new BigDecimal("3").multiply(new BigDecimal("100.1")).divide(new BigDecimal("233"),2,ROUND_HALF_UP).setScale(2,ROUND_HALF_UP);System.out.println("先乘再除,输出:"+result2);}
先乘再除,输出:1.29

        这样我们会避免了除法除不尽带来的精度丢失问题,实际结果应该为1.29

        总结

         1.金额计算中,避免先除后乘精度丢失,应先乘后除

         2.金额分摊中,应该使用最后一件用减法的方式,分摊

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

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

相关文章

[Docker]三.Docker 部署nginx,以及映射端口,挂载数据卷

一.Docker 部署 Nginx 以及端口映射 Docker 部署 Nginx,首先需要下载nginx镜像,然后启动这个镜像,就运行了一个nginx的容器了 1.下载 nginx 镜像并启动容器 #查看是否存在nginx镜像:发现没有nginx镜像 [rootlocalhost zph]# docker images | grep nginx#下载nginx镜像 [rootl…

安装 GMP、NTL、CTMalloc ,编译 OpenFHE

参考文献&#xff1a; [ABB22] Al Badawi A, Bates J, Bergamaschi F, et al. Openfhe: Open-source fully homomorphic encryption library[C]//Proceedings of the 10th Workshop on Encrypted Computing & Applied Homomorphic Cryptography. 2022: 53-63.openfheorg/o…

【Spring】IOC容器与Bean的常用属性配置

文章目录 1.前言2.IOC容器2.1 BeanFactory 容器2.2 ApplicationContext 容器 3.Bean的常用属性配置4. 总结 1.前言 在之前的文章-IOC的快速入门中讲过Bean这个概念. 本来就来介绍容器与Bean的常用属性配置 在Spring框架中&#xff0c;Bean指的是被Spring加载生成出来的对象。 …

12、SpringCloud -- redis库存和redis预库存保持一致、优化后的压测效果

目录 redis库存和redis预库存保持一致问题的产生需求:代码:测试:优化后的压测效果之前的测试数据优化后的测试数据redis库存和redis预库存保持一致 redis库存是指初始化是从数据库中获取最新的秒杀商品列表数据存到redis中 redis的预库存是指每个秒杀商品每次成功秒杀之后…

永恒之蓝漏洞 ms17_010 详解

文章目录 永恒之蓝 ms 17_0101.漏洞介绍1.1 影响版本1.2 漏洞原理 2.信息收集2.1 主机扫描2.2 端口扫描 3. 漏洞探测4. 漏洞利用5.后渗透阶段5.1创建新的管理员账户5.2开启远程桌面5.3蓝屏攻击 永恒之蓝 ms 17_010 1.漏洞介绍 永恒之蓝&#xff08;ms17-010&#xff09;爆发于…

安装虚拟机(VMware)保姆级教程及配置虚拟网络编辑器和安装WindowsServer以及宿主机访问虚拟机和配置服务器环境

目录 一、操作系统 1.1.什么是操作系统 1.2.常见操作系统 1.3.个人版本和服务器版本的区别 1.4.Linux的各个版本 二、VMware Wworkstation Pro虚拟机的安装 1.下载与安装 注意&#xff1a;VMWare虚拟网卡 2.配置虚拟网络编辑器 三、安装配置 WindowsServer 1.创建虚拟…

自动化项目实战 [个人博客系统]

自动化博客项目 用户注册登录验证效验个人博客列表页博客数量不为 0 博客系统主页写博客 我的博客列表页效验 刚发布的博客的标题和时间查看 文章详情页删除文章效验第一篇博客 不是 "自动化测试" 注销退出到登录页面,用户名密码为空 用户注册 Order(1)Parameterized…

QT5.15在Ubuntu22.04上编译流程

在我们日常遇到的很多第三方软件中&#xff0c;有部分软件针对开发人员&#xff0c;并不提供预编译成果物&#xff0c;而是需要开发人员自行编译&#xff0c;此类问题有时候不是问题&#xff08;编译步骤的doc详细且清晰时&#xff09;&#xff0c;但有时候又很棘手&#xff08…

数据结构上机实验——二叉树的实现、二叉树遍历、求二叉树的深度/节点数目/叶节点数目、计算二叉树度为1或2的节点数、判断二叉树是否相似

文章目录 数据结构上机实验1.要求2.二叉树的实现2.1创建一颗二叉树2.2对这棵二叉树进行遍历2.3求二叉树的深度/节点数目/叶节点数目2.4计算二叉树中度为 1 或 2 的结点数2.5判断2棵二叉树是否相似&#xff0c;若相似返回1&#xff0c;否则返回0 3.全部源码测试&#xff1a;Bina…

问题 S: 一只小蜜蜂...(初始化dp)

1.注意点&#xff1a; 该题递推公式为斐波那契数列&#xff0c;而n达到50&#xff0c;是非常大的数 &#xff0c; 故应用循环代替递归&#xff0c;同时记录数据 同时用long long数组储存 ​​ 2.注意点&#xff1a;初始化起点&#xff0c;切忌重新递归找数 可以直接初始化所…

前端重新部署如何通知用户更新

标题解决方案 常用的webSocket解决方案 webSocket; 大致逻辑思考应该是前端在部署好后向服务器发送一个状态变更通知&#xff1b;服务器接收后主动向前端push&#xff1b;前端通过心跳检测&#xff0c;接收到相关更新时弹出提示&#xff0c;让用户确认更新&#xff1b; 缺点&a…

什么是Props?

Props是Vue框架中的一个特性&#xff0c;用于父组件向子组件传递数据。它允许父组件将数据传递给子组件&#xff0c;并在子组件中进行使用和显示。 Props的作用是实现父子组件之间的数据通信。通过Props&#xff0c;父组件可以向子组件传递数据&#xff0c;使得子组件能够接收…

设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)

初始化及打印函数 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #define MaxSize 10//定义最大长度 int InitArr[10] { 1,2,3,4,5,6,7,8,9,10 };typedef struct {int data[MaxSize];//用静态的数据存放数据元素int length;//顺序表当前长度 }Sqlist;//顺序表的类…

java利用StringTokenizer分割字符串

介绍 利用java.util.StringTokenizer的方法&#xff0c;可以将一个字符串拆分为一系列的标记&#xff08;token&#xff09;。StringTokenizer是为了兼容性原因而保留的遗留类。在新的代码中&#xff0c;不建议使用StringTokenizer&#xff0c;而建议使用String类的split方法来…

Ubuntu自建git服务器

Ubuntu 安装 gitlab-ce sudo apt-get update sudo apt-get install gitlab-ce 安装成功 sudo apt-get install gitlab-ce 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 下列【新】软件包将被安装&#xff1a;gitlab-ce 升…

假如我有一台服务器

如果我有一台服务器&#xff0c;我会认真考虑如何充分利用它的潜力来实现自己的创意项目或支持社区。服务器是一个强大的工具&#xff0c;可以用于各种用途&#xff0c;下面我将分享一些潜在的想法&#xff1a; 1. 创意项目的托管&#xff1a; 首先&#xff0c;我会考虑托管自…

私有云:【5】安装VCenter Server

私有云&#xff1a;【5】安装VCenter Server 1、在本地物理机上安装VCenter Server到Esxi1.1、开始安装第一阶段1.2、开始安装第二阶段 2、配置VCenter2.1、分配许可2.2、添加主机2.3、创建数据存储NFS 1、在本地物理机上安装VCenter Server到Esxi 安装前在AD域服务器配置好VC…

HDU 1062:字符串反转

【题目来源】http://acm.hdu.edu.cn/showproblem.php?pid1062【题目描述】 Ignatius likes to write words in reverse way. Given a single line of text which is written by Ignatius, you should reverse all the words and then output them.【输入格式】 The input cont…

MAYA教程之建模基础命令介绍

基础命令 视图相关操作 旋转视图 : ALT 鼠标左键平移视图 : ALT 鼠标中键缩放视图 : 滚动鼠标滚轮 或者 ALT 鼠标右键切换视图 : 空格键回到模型 : F 视图状态 选择状态 : Q移动状态 : W旋转状态 : E缩放状态 : R 视图显示 正常显示 : 1正常圆滑同时显示 : 2圆滑显示 …

MySQL - 覆盖索引、索引下推

覆盖索引&#xff08;Covering Index&#xff09; &#xff1a; 覆盖索引是一种索引&#xff0c;包含了查询中需要的所有列&#xff0c;而不仅仅是索引列本身。这种索引可以通过减少磁盘I/O和提高查询性能来优化数据库查询。当一个查询可以完全通过覆盖索引满足时&#xff0c;数…