关于bigDecimal类的精度保留方法

 更新时间:2023年07月04日 10:33:28   作者:weixin_39923623  
这篇文章主要介绍了关于bigDecimal类的精度保留方法,计算机存储的浮点数受存储bit位数影响,只能保证一定范围内精准,超过bit范围的只能取近似值,Java使用java.math.BigDecimal专门处理小数精度,需要的朋友可以参考下

一、计算机的小数计算

计算机的小数计算一定范围内精确,超过范围只能取近似值:

计算机存储的浮点数受存储bit位数影响,只能保证一定范围内精准,超过bit范围的只能取近似值。

java中各类型的精度范围参见:关于java中基本数据类型的数值范围

编程时注意:

doulbe类型的数,不能用等号判定是否相等(或者是一定范围内可以)。因为两次同样的计算(除法)结果可能出现小数部分不同。甚至极端的时候,初始化两个小数时,都可能不相等(用数值和字符串分别初始化bigdecimal的小数就会不等)

java小数处理方法的经验总结:

(1)小数计算对精度无要求时,使用float节省时间。

(2)如果有精度要求,用BigDecimal类处理(初始化必须使用字符串,因为用数值初始化会得到近似值,不准确),然后设置保留位数和 舍入法(half_up四舍五入,half_even银行家,half_down向下取整)

(3)精度要求低时可转化为整数处理(集体统一扩大数量级):

乘以10的级数转化为整数处理,小数点右移几位,但整数值不要超过对应类型的取值范围。比如保留4位小数,可统一乘以10000,然后只保留整数计算结果,保留近位的话就多乘一位。

这种方式在RTB项目MDSP的算法核心模块中使用,几十万的投放量,用int或long就可以处理,更大范围的整数处理BigInteger。

这样的好处是:

a,计算快,除了除法,其他运算上整数计算(加减乘)节省时间;

b,除法中,小数部分可直接省略,或向上取整(小数大于0时则加1)也可以让小数点多移动一位来保留进位。

二、java专门的小数运算类:

BigDecimal类型(比double和float小数运算更精准的小数计算)

float和double只能用来做科学计算或者是工程计算,在广域数值范围上提供较为精确的快速近似计算;而在商业计算要求结果精确(比如,有的编程语言中提供了专门的货币类型来处理),所以Java使用java.math.BigDecimal专门处理小数精度

构造器描述:

BigDecimal(int) 创建一个具有参数所指定整数值的对象。

BigDecimal(double) 创建一个具有参数所指定双精度值的对象。

BigDecimal(long) 创建一个具有参数所指定长整数值的对象。

BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。

使用原则:初始化小数必须用String来够造,BigDecimal(String),因为用double的小数是近似值,不是精确值。

BigDecimal成员方法

add(BigDecimal) 对象自身与参数相加,然后返回这个对象。

subtract(BigDecimal) 对象自身与参数相减,然后返回这个对象。

multiply(BigDecimal) 对象自身与参数相乘,然后返回这个对象。

divide(BigDecimal) 对象自身与参数相除,然后返回这个对象。

toString() BigDecimal对象的数值转换成对应的字符串。

doubleValue() BigDecimal对返回double值。

floatValue() BigDecimal对返回float。

longValue() BigDecimal对返回long值。

intValue() BigDecimal对返回int值。

三、java小数保留精度的舍入方式

1,java 常用的四舍五入法实现:

Math类中的round方法不能设置保留几位小数,但可以乘100达到保留2位的目的:

Math.round(value*100)/100.0;

或者,直接用java.text.DecimalFormat指定保留几位小数,用哪几种舍入法:

DecimalFormat decFormat = new DecimalFormat("#.00");
decFormat.setRoundingMode(RoundingMode.HALF_UP);

2,java的8种舍入方式:

1、 ROUND_UP:向上取整(丢掉小数,整数加1) 远离零方向舍入。向绝对值最大的方向舍入,只要舍弃位非0即进位。

2、ROUND_DOWN:向下取整(丢掉小数)。趋向零方向舍入。向绝对值最小的方向输入,所有的位都要舍弃,不存在进位情况。

3、ROUND_CEILING:向正无穷方向走,始终不会减少计算值。如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;如果为负,则舍入行为与 ROUND_DOWN 相同。Math.round()方法就是使用的此模式。

4、ROUND_FLOOR:向负无穷方向舍入。向负无穷方向靠拢。若是正数,舍入行为类似于ROUND_DOWN;若为负数,舍入行为类似于ROUND_UP。

5、 HALF_UP:四舍五入,最近数字舍入(5进)。

6、 HALF_DOWN:四舍六入,最近数字舍入(5舍)。

7、 HAIL_EVEN:银行家舍入法。四舍六入五偶舍。即舍弃位4舍6入,当为5时看前一位,奇进偶舍。向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

也就是说,如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同; 如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。

注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。

8、ROUND_UNNECESSARY 断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。

到此这篇关于关于bigDecimal类的精度保留方法的文章就介绍到这了,更多相关bigDecimal精度保留内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Bean的实例化之属性注入源码剖析过程

    Spring Bean的实例化之属性注入源码剖析过程

    本篇文章主要就是分析Spring源码剖析-Bean的实例化-属性注入的相关知识,通过本文学习AbstractAutowireCapableBeanFactory#populateBean 方法的主要功能就是属性填充,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • 多模块的springboot项目发布指定模块的脚本方式

    多模块的springboot项目发布指定模块的脚本方式

    该文章主要介绍了如何在多模块的SpringBoot项目中发布指定模块的脚本,作者原先的脚本会清理并编译所有模块,导致发布时间过长,通过简化脚本,只使用`mvn clean install`命令,可以快速发布指定模块及其依赖的模块
    2025-01-01
  • springboot中spring.profiles.include的妙用分享

    springboot中spring.profiles.include的妙用分享

    这篇文章主要介绍了springboot中spring.profiles.include的妙用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • springboot 如何使用jedis连接Redis数据库

    springboot 如何使用jedis连接Redis数据库

    这篇文章主要介绍了springboot 使用jedis连接Redis数据库的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • springBoot快速访问工程目录下的静态资源

    springBoot快速访问工程目录下的静态资源

    springboot工程,是没有webapp文件夹的,静态文件放在src/main/resources/static文件夹下即可,模板文件放在src/main/resources/templates下,本文给大家介绍springBoot快速访问工程目录下的静态资源的相关知识,一起看看吧
    2021-06-06
  • Java如何接收XML格式参数并转换为JSON

    Java如何接收XML格式参数并转换为JSON

    在 Java 应用程序中,处理 XML 数据并将其转换为 JSON 格式是很常见的任务,这篇文章为大家整理了一下具体的实现方法,希望对大家有所帮助
    2025-03-03
  • Activiti开发环境的搭建过程详解

    Activiti开发环境的搭建过程详解

    这篇文章主要介绍了Activiti开发环境的搭建过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • SpringBoot整合Apache Ignite的实现

    SpringBoot整合Apache Ignite的实现

    本文主要介绍了SpringBoot整合Apache Ignite的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • java线程池参数位置导致的夺命故障宿主机打不开

    java线程池参数位置导致的夺命故障宿主机打不开

    这篇文章主要为大家介绍了java线程池参数位置导致的夺命故障宿主机打不开的问题解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • java基于servlet实现文件上传功能解析

    java基于servlet实现文件上传功能解析

    这篇文章主要为大家详细介绍了java基于servlet实现上传功能,后台使用java实现,前端主要是js的ajax实现,感兴趣的小伙伴们可以参考一下
    2016-05-05

最新评论