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

news2024/9/29 17:28:36

在这里插入图片描述

引出


在一个计算费用的场景中,用到了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变成19
            df = 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方法是个不错的选择;

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

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

相关文章

Java集合框架:List、Set、Map类型及泛型详解

文章目录 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。&#x1f30e;跑过十五…

干货!BIM高性能3D Web轻量化引擎——HOOPS Communicator!

HOOPS Communicator是一款简单而强大的工业级高性能3D Web可视化开发包&#xff0c;专注于Web端工程图形渲染。采用了先进的流式加载方式&#xff0c;并支持服务端和客户端渲染&#xff0c;是可以在云端进行部署和无缝集成的新技术平台。灵活且易于部署&#xff0c;可在以工程为…

你绝对不知道的接口加密解决方案:Python的各种加密实现

在现代软件开发中&#xff0c;接口测试已经成为了不可或缺的一部分。随着互联网的普及&#xff0c;越来越多的应用程序都采用了接口作为数据传输的方式。接口测试的目的是确保接口的正确性、稳定性和安全性&#xff0c;从而保障系统的正常运行。 在接口测试中&#xff0c;加密…

InterfaceWave 架构图

场景 正在开发一个Web应用&#xff0c;接口中很多重复逻辑&#xff08;重复逻辑已经被抽象&#xff09;&#xff0c;我使用一个Adapter适配器&#xff0c;就可以自己生成接口&#xff0c;不用再一个一个C S D 写重复逻辑&#xff0c;我只需要在配置文件中配置&#xff0c;接口…

软件测试外包干了4年,感觉废了...

​先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…

Nokogiri库和OpenURI库使用HTTP做一个爬虫

Nokogiri和OpenURI是两个常用的Ruby库&#xff0c;用于编写爬虫程序。它们的主要功能如下&#xff1a; 1、Nokogiri&#xff1a;Nokogiri是一个强大的HTML和XML解析库&#xff0c;可以用于解析网页内容。它提供了一组简单易用的API&#xff0c;可以方便地遍历和操作HTML或XML文…

对遗留系统的处理——(二)具体方法

对于遗留系统的分析和评价&#xff0c;具体方法是按照业务评价分值和技术水平分值的情况&#xff0c;把评价结果分为4种类型&#xff0c;如下图所示。 &#xff08;1&#xff09;改造 &#xff08;2&#xff09;继承 &#xff08;3&#xff09;淘汰 &#xff08;4&#xff09;集…

如何 通过使用优先级提示,来控制所有网页资源加载顺序

当你打开浏览器的网络标签时&#xff0c;你会看到大量的活动。资源正在下载&#xff0c;信息正在提交&#xff0c;事件正在记录&#xff0c;等等。 由于有太多的活动&#xff0c;有效地管理这些流量的优先级变得至关重要。带宽争用是真实存在的&#xff0c;当所有请求同时触发时…

前端知识储备

前端知识储备 一. 什么是前端? """ 任何与用户直接打交道的操作界面都可以称之为前端 比如:电脑界面 手机界面 平板界面什么是后端后端类似于幕后操作者(一堆让人头皮发麻的代码)不直接跟用户打交道 """ 二. 为什么学前端? ""&quo…

基于springboot实现校友社交平台管理系统项目【项目源码+论文说明】

基于springboot实现校友社交平台管理系统演示 摘要 校友社交系统提供给用户一个校友社交信息管理的网站&#xff0c;最新的校友社交信息让用户及时了解校友社交动向,完成校友社交的同时,还能通过论坛中心进行互动更方便。本系统采用了B/S体系的结构&#xff0c;使用了java技…

【阅读和学习代码】VoxelNet

文章目录 将点特征 转换为 voxel 特征 将点特征 转换为 voxel 特征 https://github.com/skyhehe123/VoxelNet-pytorch/blob/master/data/kitti.py 【Python】np.unique() 介绍与使用 self.T &#xff1a; # maxiumum number of points per voxel def preprocess(self, lidar…

直播预告 | YashanDB 2023年度发布会正式定档11月2日,邀您共同见证国产数据库发展实践!

11月2日&#xff0c;YashanDB 2023年度发布会将于云端直播开启&#xff0c;发布会以 「惟实励新」 为主题&#xff0c;邀请企业用户、合作伙伴、广大开发者共同见证全新产品与解决方案。届时发布会将在墨天轮社区同步进行&#xff0c;欢迎大家报名&#xff01; 惟实求真。Yasha…

在线设计数据库表用Itbuilder,极简易用真香!!!

“如果您想要一个具有快速搜索运行的高性能数据库&#xff0c;那么数据库设计是必不可少的&#xff0c;花时间设计数据库将帮助您避免效率低下和高冗余等问题”。 在线数据库设计软件itbuilder&#xff0c;界面清爽漂亮&#xff0c;功能简洁&#xff0c;没有多余设置很容易上手…

CE-LVD证书跟CE-EMC证书有什么区别?

CE-LVD证书跟CE-EMC证书有什么区别&#xff1f; CE-LVD证书跟CE-EMC证书有什么区别&#xff1f; 近日&#xff0c;TEMU平台电器需提交CE-LVD证书&#xff0c;不再接受EMC证书---玩具产品需提交满足玩具法规的CE证书&#xff0c;法规总是多变的&#xff0c;卖家也是很苦恼&…

雪糕冰淇淋经营配送小程序商城效果如何

雪糕冰淇淋是很多年轻人喜欢的食品之一&#xff0c;市面上的雪糕品牌类型众多&#xff0c;销售模式主要为厂家批发、经销商零售等&#xff0c;由于雪糕冰淇淋的易化性&#xff0c;很多用户会选择就近购买&#xff0c;但制作技术升级和长途冷藏技术下&#xff0c;网购成为另一种…

Remote Local File Inclusion (RFI/LFI)-文件包含漏洞

在Web应用开发过程中,程序开发者经常会把具有某一功能的部分代码封装起来形成独立的文件,在后续想实现该功能时,就不需要重复编写,直接调用文件,大大提高编程效率。这种调用文件的过程一般被称为文件包含。开发人员为了使代码更灵活,会将被包含的文件设置为变量,用来进行…

基于LDA的隐式标签协同过滤推荐算法_文勇军

, 王全民等人[14]提出了一种交替奇异值分解算法 (ASVD),即结合协同过滤和隐语义分析的混合推荐 算法。唐泽坤等人[15]融合聚类算法和协同过滤推荐 算法,取得了一定效果。高娜等人[16⁃19]将标签因子 和协同过滤推荐算法结合研究缓解了数据稀疏问题,但这…

2023年【安全生产监管人员】考试报名及安全生产监管人员复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全生产监管人员考试报名是安全生产模拟考试一点通总题库中生成的一套安全生产监管人员复审考试&#xff0c;安全生产模拟考试一点通上安全生产监管人员作业手机同步练习。2023年【安全生产监管人员】考试报名及安全…

找游戏外包开发游戏,有哪些好处呢?

游戏外包开发是将游戏开发的一部分或全部工作交给专业的外部开发团队或公司完成的做法。这种方法有许多潜在的好处&#xff0c;包括&#xff1a; 降低成本&#xff1a;游戏外包通常可以降低游戏开发成本&#xff0c;因为外包开发公司通常可以提供更具竞争力的价格。这是因为它…

Linux下的文件操作和文件管理

文章目录 应用编程文件操作文件描述符open函数write函数read函数close函数lseek函数文件操作例子 文件管理文件基本知识文件类型文件共享空洞文件错误处理退出程序原子操作fcntl和ioctl截断文件stat函数软链接和硬链接 应用编程 系统调用(system call)是Linux内核提供给应用层…