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

BigDecimal应用——计算费用场景中用到Integer,Double,BigDecimal三种类型出现的意外情况 结合BigDecimal源码分析

在这里插入图片描述

引出


在一个计算费用的场景中,用到了Integer,Double,BigDecimal三种类型,在转换为bigdecimal的时候遇到的问题,结合源码进行了分析。

  • 1.在new bigdecimal的时候,最好传入的是字符串;
  • 2.double类型在计算费用的场景中尽量不要用,会有意想不到的结果;
  • 3.有时候用一下BigDecimal.valueOf方法是个不错的选择;

背景描述

最近在做一个物流相关的项目,其中有一个计算运费的模块,接收前端传的参数如下如所示

在这里插入图片描述

业务逻辑

然后需要根据这两个值,重量和体积计算运费,计算的业务逻辑如下所示

重量计算方法:

取重量和体积两者间较大的数值,体积计算方法:长(cm)×*宽(cm)*×高(cm)/轻抛系数

普快:

同城互寄:12000

城内寄件:12000

跨省寄件:12000

经济区互寄(京津翼、江浙沪皖、川渝):6000

经济区互寄(黑吉辽):9000


计费重量小数点规则:

不满1kg,按1kg计费;

10KG以下:以0.1kg为计重单位,四舍五入保留 1 位小数;

10-100KG:续重以0.5kg为计重单位,不足0.5kg按0.5kg算,四舍五入保留 1 位小数;

100KG及以上:四舍五入取整;

举例:

8.4kg按照8.4kg收费

8.5kg按照8.5kg收费

8.8kg按照8.8kg收费

18.1kg按照18.5kg收费

18.5kg按照18.5kg收费

18.7kg按照19kg收费

108.4kg按照108kg收费

108.5kg按照109kg收费

108.6kg按照109kg收费

总运费小数点规则:按四舍五入计算,精确到小数点后一位

我的方法及问题

由于double类型计算金钱相关的在Java中尽量不用,因此我把他们都转成bigdecimal进行计算,我写的代码如下

在这里插入图片描述

    public static BigDecimal get(BigDecimal weight){if (weight.compareTo(new BigDecimal(1))<=0){weight = new BigDecimal(1); // 不满1kg,按照1kg计算return weight;}if (weight.compareTo(new BigDecimal(10))<=0){ // 10kg 以下DecimalFormat df = new DecimalFormat("#.0");String formattedNumber = df.format(weight);return new BigDecimal(formattedNumber);}// 四舍五入的计费规则DecimalFormat df = new DecimalFormat("#"); // 100kg 以上df.setRoundingMode(RoundingMode.HALF_UP);if (weight.compareTo(new BigDecimal(100))>0){return new BigDecimal(df.format(weight));}// 以0.5位计重单位BigDecimal remainder = weight.remainder(BigDecimal.ONE); // 小数部分BigDecimal integerPart = weight.divide(BigDecimal.ONE, BigDecimal.ROUND_DOWN); // 整数部分if (remainder.compareTo(new BigDecimal(0.5))>0){weight = weight.add(new BigDecimal(1)); // 18.7变成19df = new DecimalFormat("#.0");String formattedNumber = df.format(weight);return new BigDecimal(formattedNumber);}return new BigDecimal("1").add(integerPart);}

测试遇到的问题

测试的时候,发现输出的结果有些能对的上,有些就显得很奇怪,一开始百思不得其解,后来突然想到这个是不是浮点数的原因,再看我传的参数

在这里插入图片描述

我传的参数其实是double类型

在这里插入图片描述

idea其实也给了提示,我也忽略了这一条提醒

在这里插入图片描述

问题的对比分析

如果传的是一个double类型,比如18.8,则会出现下面的情况

在这里插入图片描述

如果用的是valueOf的方法,则不会出现上述的问题

在这里插入图片描述

源码分析

遇到上述问题后,好奇的Arya猫病又犯了,于是去翻了一下源码,发现了问题的所在,且听说来分析分析

1.valueOf方法

valueOf实际调用了什么方法

在这里插入图片描述

2.new BigDecimal(double d)方法

传入double类型的构造方法如下,调了double的这个方法:doubleToLongBits

在这里插入图片描述

这个方法干了啥事,把double类型用long类型的位表示

在这里插入图片描述

3.问题的本质

在这里插入图片描述


总结

1.在new bigdecimal的时候,最好传入的是字符串;
2.double类型在计算费用的场景中尽量不要用,会有意想不到的结果;
3.有时候用一下BigDecimal.valueOf方法是个不错的选择;

相关文章:

BigDecimal应用——计算费用场景中用到Integer,Double,BigDecimal三种类型出现的意外情况 结合BigDecimal源码分析

引出 在一个计算费用的场景中&#xff0c;用到了Integer&#xff0c;Double&#xff0c;BigDecimal三种类型&#xff0c;在转换为bigdecimal的时候遇到的问题&#xff0c;结合源码进行了分析。 1.在new bigdecimal的时候&#xff0c;最好传入的是字符串&#xff1b;2.double类…...

数据抓取可以应用到哪些行业

随着互联网的发展&#xff0c;数据已经成为人们生活中不可或缺的一部分。数据抓取作为获取数据的重要手段之一&#xff0c;也被广泛应用于各个行业。本文将探讨数据抓取在各个行业中的应用。 首先&#xff0c;让我们来了解一下数据抓取的基本概念。数据抓取是指通过一定的技术…...

目标检测YOLO实战应用案例100讲-面向小目标检测的多尺度特征融合(续)

目录 3.3 实验结果及分析 3.3.1 实验设置 3.3.2 消融实验 3.3.3 在PASCAL VOC2007上的结果...

如何选择适合的美颜SDK?

美摄美颜SDK是一款专门为企业提供美颜技术支持的SDK&#xff0c;可以帮助企业开发出具有高品质美颜效果的移动应用。本文将介绍美摄美颜SDK的技术特点和面向企业提供的技术支持。 一、技术特点 美摄美颜SDK采用了先进的图像处理技术和人工智能算法&#xff0c;能够快速准确地…...

Spring-底层架构核心概念

Spring底层核心组件 BeanDefinition BeanDefinition表示Bean定义&#xff0c;有很多属性用来描述Bean的特点&#xff1a; class&#xff0c;表示Bean类型 scope&#xff0c;表示Bean作用域&#xff0c;单例或原型等 lazyInit&#xff1a;表示Bean是否是懒加载 initMethod…...

RabbitMQ初入门

1、RabbitMQ是什么 RabbitMQ是“实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff08;亦称面向消息的中间件&#xff09;。RabbitMQ服务器是用Erlang语言编写的&#xff0c;而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均…...

电脑定时关机

电脑定时关机 1.右键 管理 2. 3. 4. 5. shutdown.exe/s /f /t 06.点击完成就好了 7.这里面可以 看到定时任务和启动 右键有运行 结束 禁用...

【算法】滑动窗口题单——4.不定长滑动窗口(求子数组个数)

文章目录 前言2799. 统计完全子数组的数目解法1——枚举右端点&#xff0c;移动左端点解法2——枚举左端点&#xff0c;扩展右端点 713. 乘积小于 K 的子数组1358. 包含所有三种字符的子字符串数目2302. 统计得分小于 K 的子数组数目2537. 统计好子数组的数目2762. 不间断子数组…...

CMake aux_source_directory 学习

如下&#xff0c;prj是空文件夹&#xff1b; add.h; #include <iostream>using namespace std;int add1(int a, int b); num.h; int num1100; int num2301; add.cpp&#xff1b; #include "add.h"int add1(int i, int j) {return i j; } main.cpp&#x…...

Mybatis中延迟加载~

延迟加载&#xff1a; 等一会加载&#xff0c;在多表关联查询操作的时候可以使用到的一种方案&#xff0c;如果是单表操作就完全没有延迟加载的概念。 多表查询例如&#xff0c;查询用户和部门信息&#xff0c;如果我们仅仅只是需要用户的信息&#xff0c;而不需要用户对应的…...

【C语言】memmove()函数(拷贝重叠内存块函数详解)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.memmove()函数简介 1.函数功能 2.函数参数 1>.void * destination 2>.onst void * source 3>.size_t num 3.函数返回值 4.函数头文件 二.memmove()函数…...

04-流媒体-ffmpeg.c源码分析

ffmpeg.c是一个使用ffmpeg库的参考代码,实现了视频格式转换的功能,类似于我们常用的格式工产,源代码的的目录是: ffmpeg-4.2.2/fftools/ffmpeg.c 和前面的ffplay一样,我们分析其源代码,主要只是为了让读者了解ffmpeg.c此文件的大概流程,并且熟悉常用的ffmpeg库的API。 下…...

迭代器 Iterator

迭代器是一种设计模式&#xff0c;它用于遍历集合或容器中的元素&#xff0c;能够访问集合的元素而无需关心集合的内部结构&#xff1a; 特点&#xff1a; 封装集合访问&#xff1a;迭代器封装了对集合元素的访问&#xff0c;通过迭代器访问集合中的元素&#xff0c;而无需了…...

掌握CSS Flexbox,打造完美响应式布局,适配各种设备!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 基…...

FlutterUnit 周边 | 收录排序算法可视化

theme: cyanosis 1. FlutterUnit 更新&#xff1a;排序算法可视化 排序算法可视化是用视图层表现出算法执行过程中排序的过程&#xff0c;感谢 编程的平行世界 在 《十几种排序算法的可视化效果&#xff0c;快来看看&#xff01;&#x1f440;》》 一文中提供的算法支持。我进行…...

代码随想录Day30 贪心05 LeetCode T435无重叠区间 T763划分字母区间 T56 合并区间

LeetCode T435 无重叠区间 题目链接:435. 无重叠区间 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 这题思路和昨天的打气球类似,我们需要按照左区间或者右区间进行排序,然后哦判断第i个区间的左端点和第i-1个区间的右端点的大小关系,,如果大于等于,那么就无需操作,一旦…...

发展高质量存储力,中国高科技力量聚浪成潮

中国信息通信研究院指出&#xff0c;在全球数字化转型与产业变革的浪潮下&#xff0c;算力正在成为改变全球竞争格局的关键力量。而根据最新的《算力基础设施高质量发展行动计划》&#xff0c;算力是集信息计算力、数据存储力和网络运载力于一体的新型生产力。当前&#xff0c;…...

修改svc的LoadBalancer的IP引发的惨案

文章目录 背景修改externalIPs的操作api-server报错日志挽救教训 背景 k8s集群没有接外部负载均衡&#xff0c;部署istio的时候ingressgateway一直pending。 于是手动修改了这个lb svc的externalIP&#xff0c;于是k8s就崩了&#xff0c;如何崩的&#xff0c;且听我还道来。 …...

2520. 统计能整除数字的位数

2520. 统计能整除数字的位数 class Solution {public int countDigits(int num) {int res 0;int o num;while (num > 0) {if (o % (num % 10) 0) {res 1;}num num / 10;}return res;} }...

BeanUtils.copyProperties的用法

常见场景 我们如果有两个具有很多相同属性名的JavaBean对象a和b&#xff0c;想把a中的属性赋值到b&#xff0c;例如 接口中将接收到的前端请求参数XxxReqVo,我们想把这个入参转化为XxxQuery对象作为数据库的查询条件对象 传统做法是手动set&#xff0c;即 XxxQuery xxxQuer…...

【RabbitMQ 实战】12 镜像队列

一、镜像队列的概念 RabbitMQ的镜像队列是将消息副本存储在一组节点上&#xff0c;以提高可用性和可靠性。镜像队列将队列中的消息复制到一个或多个其他节点上&#xff0c;并使这些节点上的队列保持同步。当一个节点失败时&#xff0c;其他节点上的队列不受影响&#xff0c;因…...

PyCharm社区版安装

PyCharm社区版安装 到中国官网下载 https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows 首次创建项目&#xff0c;会自动下载安装Python 3.9 社区版的区别 社区版的区别...

【LeetCode每日一题合集】2023.10.16-2023.10.22(只出现一次的数字Ⅲ)

文章目录 260. 只出现一次的数字 III⭐&#xff08;异或&#xff09;&#x1f402;2652. 倍数求和解法1——枚举模拟解法2—— O ( 1 ) O(1) O(1)容斥原理相似题目——1201. 丑数 III&#xff08;二分查找容斥原理&#xff09; 2530. 执行 K 次操作后的最大分数解法1——贪心优…...

尚硅谷大数据项目《在线教育之实时数仓》笔记003

视频地址&#xff1a;尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第7章 数仓开发之ODS层 P015 第8章 数仓开发之DIM层 P016 P017 P018 P019 01、node001节点Linux命令 02、KafkaUtil.java 03、DimSinkApp.java P020 P021 P022 P023 第7章 数…...

【Linux】部署单体项目以及前后端分离项目(项目部署)

一、简介 以下就是Linux部署单机项目和前后端分离项目的优缺点&#xff0c;希望对你有所帮助。 1、Linux部署单机项目&#xff1a; 优点&#xff1a; 1.简化了系统管理&#xff1a;由于所有服务都在同一台机器上运行&#xff0c;因此可以简化系统管理和维护。 2.提高了性能&a…...

设计模式之门面模式

前言 什么是门面模式 门面模式是一种结构型设计模式&#xff0c;它提供了一个统一的接口&#xff0c;用来访问子系统中的一群接口。它定义了一个高层接口&#xff0c;让子系统更容易使用。这种模式常用于将一个复杂的子系统封装成一个简单的接口&#xff0c;使得客户端可以方…...

Postman的使用

Postman的使用 Postman断言Postman常用断言1、断言响应状态码2、断言包含某个字符串3、断言JSON数据4、Postman断言工作原理 Postman关联Postman自动关联创建环境 3、Postman参数化CSV文件JSON文件1、用例集的导入导出2、环境导出 Postman断言 让Postman工具代替人自动判断预期…...

QGIS008:QGIS拓扑检查、修改及验证

摘要&#xff1a;本文介绍使用QGIS拓扑检查器和几何图形检查器检查图层的拓扑错误&#xff0c;修改拓扑错误&#xff0c;并对修改后的图层进行错误验证。 实验数据&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Vy2s-KYS-XJevqHNdavv9A?pwdf06o 提取码&#xff1a…...

安装DBD-Oracle报错处理

cd DBD-Oracle-1.83 perl Makefile.PL make && make install make编译报错如下&#xff1a; /bin/ld: 找不到 -lnsl collect2: 错误&#xff1a;ld 返回 1 make: *** [Makefile:524&#xff1a;blib/arch/auto/DBD/Oracle/Oracle.so] 错误 1 [rootlocalhost DBD-Ora…...

【机器学习】KNN算法-鸢尾花种类预测

KNN算法-鸢尾花种类预测 文章目录 KNN算法-鸢尾花种类预测1. 数据集介绍2. KNN优缺点&#xff1a; K最近邻&#xff08;K-Nearest Neighbors&#xff0c;KNN&#xff09;算法是一种用于模式识别和分类的简单但强大的机器学习算法。它的工作原理非常直观&#xff1a;给定一个新数…...