热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

java中的取整与四舍五入方法实例

这篇文章主要给大家介绍了关于java中取整与四舍五入的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一.java中取整数的方式

1.直接使用强制转换

public static void roundOne(){
  System.out.println("正数:(int)10.12 = " + (int)10.12); 
  System.out.println("负数:(int)-10.12 = " + (int)-10.12); 
  System.out.println("---------------------------------");
  System.out.println("正数:(int)1011111111111111111111.12 = " + (int)1011111111111111111111.12); 
  System.out.println("负数:(int)-1011111111111111111111.12 = " + (int)-1011111111111111111111.12); 
 }

直接用强制转换的方式将浮点型数据转换为整型时,直接去掉小数点后部分的精度,取整数部分;直接强制取整有精度风险,一方面是小数位损失,另一方面当浮点型数字超过整型数字最大值时,会发生溢出。实际工程中,如果这两种因素都不会对工程产生影响,可以使用,否则不建议使用。

2.java中提供的取整的函数

java中提供了三种取整的函数:

  (1).Math.ceil(double num);

  (2).Math.floor(double num);

  (3).Math.round(double num);

 public static void roundTwo(){
  System.out.println("正数:Math.ceil(10.12) = " + Math.ceil(10.12));
  System.out.println("负数:Math.ceil(-10.12) = " + Math.ceil(-10.12));
  System.out.println("正数:Math.ceil(101111111111111111111.12) = " + Math.ceil(101111111111111111111.12));
  System.out.println("负数:Math.ceil(-101111111111111111111.12) = " + Math.ceil(-101111111111111111111.12));
  System.out.println("---------------------------------");
  System.out.println("正数:Math.floor(10.12) = " + Math.floor(10.12));
  System.out.println("负数:Math.floor(-10.12) = " + Math.floor(-10.12));
  System.out.println("正数:Math.floor(101111111111111111111.12) = " + Math.floor(101111111111111111111.12));
  System.out.println("负数:Math.floor(-101111111111111111111.12) = " + Math.floor(-101111111111111111111.12));
 }

Math.ceil(double num);函数是取浮点数的天花板数,即不小于num的最小整数;Math.floor(double num)函数是取地板数,即不大于num的最大整数。这两个函数的返回值均是double型(java中当其值大于9999999.0时,默认用科学记数法表示),如果超过没有特殊情况,或者说规则很明确,就一种规则。

public static void roundThree(){
  System.out.println("小数点后第一位=5"); 
  System.out.println("正数:Math.round(10.5) = " + Math.round(10.5)); 
  System.out.println("负数:Math.round(-10.5) = " + Math.round(-10.5)); 
  System.out.println(); 
 
  System.out.println("小数点后第一位<5"); 
  System.out.println("正数:Math.round(10.46) = " + Math.round(10.46)); 
  System.out.println("负数:Math.round(-10.46) = " + Math.round(-10.46)); 
  System.out.println(); 
 
  System.out.println("小数点后第一位>5"); 
  System.out.println("正数:Math.round(10.68) = " + Math.round(10.68)); 
  System.out.println("负数:Math.round(-10.68) = " + Math.round(-10.68));
 }

Math.round(double num)函数是取整函数,该函数只关注小数点后第一位小数值,具体规则如下:

(1).参数的小数点后第一位<5,运算结果为参数整数部分。

(2).参数的小数点后第一位>5,运算结果为参数整数部分绝对值+1,符号(即正负)不变。

(3).参数的小数点后第一位=5,正数运算结果为整数部分+1,负数运算结果为整数部分。

总结:大于五全部加,等于五正数加,小于五全不加。

二.Java中四舍五入的方法

1.使用BigDecimal对象的方式

public static void roundFour(){
  double f = 10.2345;
  BigDecimal b0 = new BigDecimal(f);
  BigDecimal b1 = new BigDecimal(f);
  BigDecimal b2 = new BigDecimal(f);
  BigDecimal b3 = new BigDecimal(f);
  BigDecimal b4 = new BigDecimal(f);
  BigDecimal b5 = new BigDecimal(f);
  BigDecimal b6 = new BigDecimal(f);
  BigDecimal b7 = new BigDecimal("10.2345");
  
  double f0 = b0.setScale(3, BigDecimal.ROUND_UP).doubleValue();
  double f1 = b1.setScale(3, BigDecimal.ROUND_DOWN).doubleValue();
  double f2 = b2.setScale(3, BigDecimal.ROUND_CEILING).doubleValue();
  double f3 = b3.setScale(3, BigDecimal.ROUND_FLOOR).doubleValue();
  double f4 = b4.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
  double f5 = b5.setScale(3, BigDecimal.ROUND_HALF_DOWN).doubleValue();
  double f6 = b6.setScale(3, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  double f7 = b7.setScale(4, BigDecimal.ROUND_UNNECESSARY).doubleValue();
  
  System.out.println(f + "使用 远离零方向舍入(ROUND_UP)方式四舍五入结果为:" + f0);
  System.out.println(f + "使用 趋向零方向舍入(ROUND_DOWN)方式四舍五入结果为:" + f1);
  System.out.println(f + "使用 向正无穷方向舍入(ROUND_CEILING)方式四舍五入结果为:" + f2);
  System.out.println(f + "使用 向负无穷方向舍入(ROUND_FLOOR)方式四舍五入结果为:" + f3);
  System.out.println(f + "使用 最近数字舍入(5进)(ROUND_HALF_UP)方式四舍五入结果为:" + f4);
  System.out.println(f + "使用 最近数字舍入(5舍)(ROUND_HALF_DOWN)方式四舍五入结果为:" + f5);
  System.out.println(f + "使用 银行家舍入法(ROUND_HALF_EVEN)方式四舍五入结果为:" + f6);
  System.out.println(f + "使用 不需要舍入模式(ROUND_UNNECESSARY)方式结果为:" + f7);
 }

BigDecimal中有8中四舍五入设置方式:

(1).ROUND_UP:远离零方向舍入。向绝对值最大的方向舍入,只要舍弃位非0即进位。

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

(3).ROUND_CEILING:向正无穷方向舍入。向正最大方向靠拢。若是正数,舍入行为类似于ROUND_UP,若为负数,舍入行为类似于ROUND_DOWN。Math.round()方法就是使用的此模式。

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

(5).ROUND_HALF_UP:最近数字舍入(5进)。这是我们最经典的四舍五入。

(6).ROUND_HALF_DOWN:最近数字舍入(5舍)。在这里5是要舍弃的。

(7).ROUND_HALF_EVEN:银行家舍入法。

(8).ROUND_UNNECESSARY:计算结果是精确的,不需要舍入模式。

    a.ROUND_HALF_DOWN解释

    第(6)中四舍五入方式ROUND_HALF_DOWN解释的是遇到5要舍弃,但10.2345保留3位小数后结果是10.235,并没有直接舍去精确位的5,还是进了1,为什么呢?

public static void roundFive(){
  //通过double类型作为参数实例化BigDecimal对象
  double f = 10.2345;
  BigDecimal b5 = new BigDecimal(f);
  System.out.println("b5:" + b5);
  double f5 = b5.setScale(3, BigDecimal.ROUND_HALF_DOWN).doubleValue();
  System.out.println("ROUND_HALF_DOWN方式处理后:" + f5);
  System.out.println("----------------------------");
  //通过字符串类型作为参数实例化BigDecimal对象
  BigDecimal b5_1 = new BigDecimal("10.2345");
  System.out.println("b5_1:" + b5_1);
  double f5_1 = b5_1.setScale(3, BigDecimal.ROUND_HALF_DOWN).doubleValue();
  System.out.println("ROUND_HALF_DOWN方式处理后:" + f5_1);
  System.out.println("----------------------------");
  //遇到的5后面有小数位0,对数据大小无影响,直接舍弃5
  BigDecimal b5_2 = new BigDecimal("10.23450");
  System.out.println("b5_2:" + b5_2);
  double f5_2 = b5_2.setScale(3, BigDecimal.ROUND_HALF_DOWN).doubleValue();
  System.out.println("ROUND_HALF_DOWN方式处理后:" + f5_2);
  System.out.println("----------------------------");
  
  //遇到的5后面有非0小数位,对数据大小有影响,会进1
  BigDecimal b5_3 = new BigDecimal("10.234501");
  System.out.println("b5_3:" + b5_3);
  double f5_3 = b5_3.setScale(3, BigDecimal.ROUND_HALF_DOWN).doubleValue();
  System.out.println("ROUND_HALF_DOWN方式处理后:" + f5_3);
  System.out.println("----------------------------");
 }

    通过例子可以看出,10.2345通过ROUND_HALF_DOWN方式保留三位小数后结果为10.235原因是,使用的double类型初始化产生的BigDecimal对象的,实际上实例化后的数值并不是10.2345,而是10.234500000000000596855898038484156131744384765625,根据样例可知,当5后面还有其他小数时,依然会向前进1位。也就是说当使用ROUND_HALF_DOWN方式时,并不是所有的5都直接舍去,需要看5后面是否有其他非0位,如果没有,直接舍去,如果有,需要进1。

    b.银行家算法

    四舍五入其实在金融方面运用的非常多,尤其是银行的利息。我们都知道银行的盈利渠道主要是利息差,它从储户手里收集资金,然后放贷出去,期间产生的利息差就是银行所获得的利润。如果我们采用平常四舍五入的规则话,这里采用每10笔存款利息计算作为模型,如下:

四舍:0.000、0.001、0.002、0.003、0.004。这些舍的都是银行赚的钱。

五入:0.005、0.006、0.007、0.008、0.009。这些入的都是银行亏的钱,

分别为:0.005、0.004、.003、0.002、0.001。

    所以对于银行来说它的盈利应该是0.000 + 0.001 + 0.002 + 0.003 + 0.004 - 0.005 - 0.004 - 0.003 - 0.002 - 0.001 = -0.005。从结果中可以看出每10笔的利息银行可能就会损失0.005元,千万别小看这个数字,这对于银行来说就是一笔非常大的损失。面对这个问题就产生了如下的银行家涉入法了。该算法是由美国银行家提出了,主要用于修正采用上面四舍五入规则而产生的误差。如下:

(1).舍去位的数值小于5时,直接舍去。

(2).舍去位的数值大于5时,进位后舍去。

(3).当舍去位的数值等于5时,若5后面还有其他非0数值,则进位后舍去,若5后面是0时,则根据5前一位数的奇偶性来判断,奇数进位,偶数舍去。

对于上面的规则我们举例说明

11.556 = 11.56          ------六入
11.554 = 11.55          -----四舍
11.5551 = 11.56         -----五后有数进位
11.545 = 11.54          -----五后无数,若前位为偶数应舍去
11.555 = 11.56          -----五后无数,若前位为奇数应进位

    c.ROUND_UNNECESSARY解释

   ROUND_UNNECESSARY方式表示计算结果是精确的,如果不是精确的,将会抛出java.lang.ArithmeticException异常。

public static void roundSix(){
  BigDecimal b7 = new BigDecimal("10.23455");
  double f7 = b7.setScale(4, BigDecimal.ROUND_UNNECESSARY).doubleValue();
  System.out.println("ROUND_UNNECESSARY方式处理后:" + f7);
 }

如果将BigDecimal b7 = new BigDecimal("10.23455")中的数字改为10.2345或10.234500000;即可正常运行。也就是说,使用ROUND_UNNECESSARY方式时,浮点数保留N位小数时,不能影响数字的精度,只要有舍弃掉数字导致精度受影响,都会抛出异常。

注:这些枚举值有时候会用RoundingMode类中的枚举值,其实效果是一样的,RoundingMode只是将BigDecimal中的枚举又封装了一层,简化了一下枚举名,无实质性差别。RoundingMode枚举类中的枚举示例:UP(BigDecimal.ROUND_UP),

2.使用DecimalFormat对象的方式

public static void roundSeven(){
  DecimalFormat df = new DecimalFormat("#.000");
  //df.setRoundingMode(RoundingMode.DOWN);
  System.out.println(df.format(new BigDecimal(10.2345)));//10.235
 }

注:DecimalFormat默认采用了RoundingMode.HALF_EVEN这种类型,可以通过setRoundingMode方法进行设置四舍五入方式,而且format之后的结果是一个字符串类型String。

3.使用String.format方式

public static void roundEight(){
  double d = 10.2345;
  String result = String.format("%.3f", d);
  System.out.println("result:" + result);
 }

输出为10.235。String.format可以格式化很多类型的数据,包括整数、浮点数、字符串、日期等,具体对浮点数的格式化规则后续详细介绍,此处只需知道浮点数的四舍五入有这种方式。

4.使用Math.round方式

public static void roundNine(){
  double d1 = Math.round(5.2644555*100)*0.01d;
  System.out.println("d1:" + d1);
  
  double d2 = Math.round(5.2654555*100)*0.01d;
  System.out.println("d2:" + d2);
 }

Math.round()方式不建议使用,因为会有风险,如样例所示。

5.使用NumberFormat方式

public static void roundTen(){
  double d = 10.2345;
  NumberFormat nf=NumberFormat.getNumberInstance() ;
  nf.setMaximumFractionDigits(2);
  String s= nf.format(d) ;
  System.out.println("s1:" + s);
  
  nf.setMaximumFractionDigits(3);
  s= nf.format(d) ;
  System.out.println("s2:" + s);
 }

总结

到此这篇关于java中取整与四舍五入的文章就介绍到这了,更多相关java取整与四舍五入内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Søren Kierkegaard famously stated that life can only be understood in retrospect but must be lived moving forward. This perspective delves into the intricate relationship between our lived experiences and our reflections on them. ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文详细介绍了如何在 Spring Boot 应用中通过 @PropertySource 注解读取非默认配置文件,包括配置文件的创建、映射类的设计以及确保 Spring 容器能够正确加载这些配置的方法。 ... [详细]
  • This document outlines the recommended naming conventions for HTML attributes in Fast Components, focusing on readability and consistency with existing standards. ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
author-avatar
哗锅_348
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有