Java语言中的取整运算(包括截尾取整,四舍五入,凑整)�

在Java中进行取整,尤其是四舍五入取整还有点麻烦。

下面是我根据网上的一些解答整理的三种取整运算(包括截尾取整,四舍五入,凑整),类似于面向过程语言(如C和Basic)中的取整函数(不过在Java中它叫类的方法,“类名.方法名(参数)”的运算都是类的静态方法)。

其中,注释掉的那段是在网上查到的有的朋友认为正确的四舍五入的取整方法,但是经过我的实验却是不正确的四舍五入的取整方法。

TestGetInt.java 源代码


import java.math.BigDecimal;

import java.text.DecimalFormat;

public class TestGetInt{

  public static void main(String[] args){

double i=2, j=2.1, k=2.5, m=2.9;

System.out.println("舍掉小数取整:Math.floor(2)=" + (int)Math.floor(i));

System.out.println("舍掉小数取整:Math.floor(2.1)=" + (int)Math.floor(j));

System.out.println("舍掉小数取整:Math.floor(2.5)=" + (int)Math.floor(k));

System.out.println("舍掉小数取整:Math.floor(2.9)=" + (int)Math.floor(m));

                                                                               

/* 这段被注释的代码不能正确的实现四舍五入取整

System.out.println("四舍五入取整:Math.rint(2)=" + (int)Math.rint(i));

System.out.println("四舍五入取整:Math.rint(2.1)=" + (int)Math.rint(j));

System.out.println("四舍五入取整:Math.rint(2.5)=" + (int)Math.rint(k));

System.out.println("四舍五入取整:Math.rint(2.9)=" + (int)Math.rint(m));

    

System.out.println("四舍五入取整:(2)=" + new DecimalFormat("0").format(i));

System.out.println("四舍五入取整:(2.1)=" + new DecimalFormat("0").format(i));

System.out.println("四舍五入取整:(2.5)=" + new DecimalFormat("0").format(i));

System.out.println("四舍五入取整:(2.9)=" + new DecimalFormat("0").format(i));

*/

System.out.println("四舍五入取整:(2)=" + new BigDecimal("2").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("四舍五入取整:(2.1)=" + new BigDecimal("2.1").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("四舍五入取整:(2.5)=" + new BigDecimal("2.5").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("四舍五入取整:(2.9)=" + new BigDecimal("2.9").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("凑整:Math.ceil(2)=" + (int)Math.ceil(i));

System.out.println("凑整:Math.ceil(2.1)=" + (int)Math.ceil(j));

System.out.println("凑整:Math.ceil(2.5)=" + (int)Math.ceil(k));

System.out.println("凑整:Math.ceil(2.9)=" + (int)Math.ceil(m));

System.out.println("舍掉小数取整:Math.floor(-2)=" + (int)Math.floor(-i));

System.out.println("舍掉小数取整:Math.floor(-2.1)=" + (int)Math.floor(-j));

System.out.println("舍掉小数取整:Math.floor(-2.5)=" + (int)Math.floor(-k));

System.out.println("舍掉小数取整:Math.floor(-2.9)=" + (int)Math.floor(-m));

System.out.println("四舍五入取整:(-2)=" + new BigDecimal("-2").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("四舍五入取整:(-2.1)=" + new BigDecimal("-2.1").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("四舍五入取整:(-2.5)=" + new BigDecimal("-2.5").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("四舍五入取整:(-2.9)=" + new BigDecimal("-2.9").setScale(0, BigDecimal.ROUND_HALF_UP));

System.out.println("凑整:Math.ceil(-2)=" + (int)Math.ceil(-i));

System.out.println("凑整:Math.ceil(-2.1)=" + (int)Math.ceil(-j));

System.out.println("凑整:Math.ceil(-2.5)=" + (int)Math.ceil(-k));

System.out.println("凑整:Math.ceil(-2.9)=" + (int)Math.ceil(-m));

    }

}

以上代码用的方法我也没有经过非常系统的学习和验证,如果哪位朋友发现问题请一定帮忙指正一下。谢谢。

5 thoughts on “Java语言中的取整运算(包括截尾取整,四舍五入,凑整)�”

  1. 在Java中把 301 除以 100 怎么写?

    如果你用 System.out.println(301/100); 输出的结果是3。

    因为Java认为你写的两个都是整数,所以结果也是整数;

    只要你把其中一个数(被除数或除数)强制转为double类型,那么结果就是double类型了。

    像这样:

    System.out.println((double)301/100);

    看来,Java不是一种方便作数学计算的语言啊。至少在我看来,还没有古老的basic方便;)

  2. 你注释的代码没有问题。

    看看rint的API文档吧。rint和round是不同的,真正的四舍五入是round方法。

    DecimalFormat你的代码有问题,都是使用的i,如果正确的话,应该看到输出的结果和rint一样,API里面也说到这个了:

    Rounding

    DecimalFormat uses half-even rounding (see ROUND_HALF_EVEN) for formatting.

  3. 谢谢Cherami的解惑:)

    上面的代码确实写错了。

    我修改了的测试代码如下,不过round(-2.5)还是不能满足需要,我需要它等于 -3, 它却等于 -2。看来,还得好好学习一下java.lang.Math的API了。

    修改后的:TestGetInt.java 源代码


    import java.math.BigDecimal;

    import java.text.DecimalFormat;

    public class TestGetInt {

    public static void main(String[] args) {

    double i = 2, j = 2.1, k = 2.5, m = 2.9;

    System.out.println("舍掉小数取整:Math.floor(" + i + ")=" + (int) Math.floor(i));

    System.out.println("舍掉小数取整:Math.floor(" + j + ")=" + (int) Math.floor(j));

    System.out.println("舍掉小数取整:Math.floor(" + k + ")=" + (int) Math.floor(k));

    System.out.println("舍掉小数取整:Math.floor(" + m + ")=" + (int) Math.floor(m));

    System.out.println();

    System.out.println("舍掉小数取整:Math.floor(-" + i + ")=" + (int) Math.floor(-i));

    System.out.println("舍掉小数取整:Math.floor(-" + j + ")=" + (int) Math.floor(-j));

    System.out.println("舍掉小数取整:Math.floor(-" + k + ")=" + (int) Math.floor(-k));

    System.out.println("舍掉小数取整:Math.floor(-" + m + ")=" + (int) Math.floor(-m));

    System.out.println();

    // 这段被注释的代码不能正确的实现四舍五入取整

    System.out.println("四舍五入取整:Math.rint(" + i + ")=" + (int) Math.rint(i));

    System.out.println("四舍五入取整:Math.rint(" + j + ")=" + (int) Math.rint(j));

    System.out.println("四舍五入取整:Math.rint(" + k + ")=" + (int) Math.rint(k));

    System.out.println("四舍五入取整:Math.rint(" + m + ")=" + (int) Math.rint(m));

    System.out.println();

    System.out.println("四舍五入取整:Math.rint(-" + i + ")=" + (int) Math.rint(-i));

    System.out.println("四舍五入取整:Math.rint(-" + j + ")=" + (int) Math.rint(-j));

    System.out.println("四舍五入取整:Math.rint(-" + k + ")=" + (int) Math.rint(-k));

    System.out.println("四舍五入取整:Math.rint(-" + m + ")=" + (int) Math.rint(-m));

    System.out.println();

    System.out.println("DecimalFormat四舍五入取整:(" + i + ")="

    + new DecimalFormat("0").format(i));

    System.out.println("DecimalFormat四舍五入取整:(" + j + ")="

    + new DecimalFormat("0").format(j));

    System.out.println("DecimalFormat四舍五入取整:(" + k + ")="

    + new DecimalFormat("0").format(k));

    System.out.println("DecimalFormat四舍五入取整:(" + m + ")="

    + new DecimalFormat("0").format(m));

    System.out.println();

    System.out.println("DecimalFormat四舍五入取整:(-" + i + ")="

    + new DecimalFormat("0").format(-i));

    System.out.println("DecimalFormat四舍五入取整:(-" + j + ")="

    + new DecimalFormat("0").format(-j));

    System.out.println("DecimalFormat四舍五入取整:(-" + k + ")="

    + new DecimalFormat("0").format(-k));

    System.out.println("DecimalFormat四舍五入取整:(-" + m + ")="

    + new DecimalFormat("0").format(-m));

    System.out.println();

    System.out.println("BigDecimal四舍五入取整:(" + i + ")="

    + new BigDecimal("2").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println("BigDecimal四舍五入取整:(" + j + ")="

    + new BigDecimal("2.1").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println("BigDecimal四舍五入取整:(" + k + ")="

    + new BigDecimal("2.5").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println("BigDecimal四舍五入取整:(" + m + ")="

    + new BigDecimal("2.9").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println();

    System.out.println("BigDecimal四舍五入取整:(-" + i + ")="

    + new BigDecimal("-2").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println("BigDecimal四舍五入取整:(-" + j + ")="

    + new BigDecimal("-2.1").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println("BigDecimal四舍五入取整:(-" + k + ")="

    + new BigDecimal("-2.5").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println("BigDecimal四舍五入取整:(-" + m + ")="

    + new BigDecimal("-2.9").setScale(0, BigDecimal.ROUND_HALF_UP));

    System.out.println();

    System.out.println("凑整:Math.ceil(" + i + ")=" + (int) Math.ceil(i));

    System.out.println("凑整:Math.ceil(" + j + ")=" + (int) Math.ceil(j));

    System.out.println("凑整:Math.ceil(" + k + ")=" + (int) Math.ceil(k));

    System.out.println("凑整:Math.ceil(" + m + ")=" + (int) Math.ceil(m));

    System.out.println();

    System.out.println("凑整:Math.ceil(-" + i + ")=" + (int) Math.ceil(-i));

    System.out.println("凑整:Math.ceil(-" + j + ")=" + (int) Math.ceil(-j));

    System.out.println("凑整:Math.ceil(-" + k + ")=" + (int) Math.ceil(-k));

    System.out.println("凑整:Math.ceil(-" + m + ")=" + (int) Math.ceil(-m));

    System.out.println();

    System.out.println("四舍五入取整:Math.round(" + i + ")=" + (int) Math.round(i));

    System.out.println("四舍五入取整:Math.round(" + j + ")=" + (int) Math.round(j));

    System.out.println("四舍五入取整:Math.round(" + k + ")=" + (int) Math.round(k));

    System.out.println("四舍五入取整:Math.round(" + m + ")=" + (int) Math.round(m));

    System.out.println();

    System.out.println("四舍五入取整:Math.round(-" + i + ")=" + (int) Math.round(-i));

    System.out.println("四舍五入取整:Math.round(-" + j + ")=" + (int) Math.round(-j));

    System.out.println("四舍五入取整:Math.round(-" + k + ")=" + (int) Math.round(-k));

    System.out.println("四舍五入取整:Math.round(-" + m + ")=" + (int) Math.round(-m));

    }

    }

  4. 再转帖一篇与这个问题有关的帖子。

    转自:(http://dev.cbw.com/java/j2se/200510195401_4327756.shtml

    **************************************************************************************************

    四舍五入-8.5后应该等于几?

    Java:Math.round(-8.5) 等于 -8

    可是

    Excel:Round(-8.5, 0) 等于 -9

    SQLServer:select round(-8.5, 0) 输出 -9

    Oracle:select round(-8.5) from dual 输出 -9

    我觉得对负数四舍五入时,可以这样理解(假设num为正数):

    Round(-num) = -Round(num),比如:Round(-8.5) = -9

    但为什么Java等于-8?是Java的Bug吗?从数学的角度来说Round(-8.5)应该等于几?

    另外,还有个奇怪的问题:

    double num=0.01+0.105;

    System.out.println(new java.text.DecimalFormat("0.00").format(num)); //输出0.11

    System.out.println(new java.text.DecimalFormat("0.00").format(0.115)); //输出0.12

    为什么结果会不同呢?

     

     

    jack1219(jack) 于 2005-10-15 1:49:11

    关注

    cutelion(MADEinCNNC) 于 2005-10-15 8:40:23

    函数定义的不同

    For_suzhen(好孟成贞) 于 2005-10-15 9:14:03

    -8

    trumplet(检查) 于 2005-10-15 9:16:40

    以下是excel的

    ROUND

    全部显示

    全部隐藏

    返回某个数字按指定位数取整后的数字。

    语法

    ROUND(number,num_digits)

    Number 需要进行四舍五入的数字。

    Num_digits 指定的位数,按此位数进行四舍五入。

    说明

    如果 num_digits 大于 0,则四舍五入到指定的小数位。

    如果 num_digits 等于 0,则四舍五入到最接近的整数。

    如果 num_digits 小于 0,则在小数点左侧进行四舍五入。

    trumplet(检查) 于 2005-10-15 9:18:17

    以下是JAVA的API:

    round

    public static long round(double a)Returns the closest long to the argument. The result is rounded to an integer by adding 1/2, taking the floor of the result, and casting the result to type long. In other words, the result is equal to the value of the expression:

    (long)Math.floor(a + 0.5d)Special cases:

    If the argument is NaN, the result is 0.

    If the argument is negative infinity or any value less than or equal to the value of Long.MIN_VALUE, the result is equal to the value of Long.MIN_VALUE.

    If the argument is positive infinity or any value greater than or equal to the value of Long.MAX_VALUE, the result is equal to the value of Long.MAX_VALUE.

    Parameters:

    a - a floating-point value to be rounded to a long.

    Returns:

    the value of the argument rounded to the nearest long value.

    See Also:

    Long.MAX_VALUE, Long.MIN_VALUE

    For_suzhen(好孟成贞) 于 2005-10-15 9:30:38

    我是学数学的,四舍五入的问题可能就像您说的那样,我头一次回答的时候可能没经过大脑

    现在想想您说得有点道理,如果-8.5四舍五入等于-8,那么-8.4呢,它又该等于多少呢?-9?

    那这个函数应该是如何定义的呢?难道是先取整,然后判断小数点后比0.5大或者是小?那-0.4 要比 -0.5大啊,为什么四舍五入后变成-9 反而小了?“-”在计算机中是用最高位为1来表示 如果10001000.1 表示是-8.5 那么按数学的理论应该舍掉小数点后面的位,在整数位加1 这样的原数变为10001001 就成了-9. 对不起大哥,我也糊涂了,看来应该这样理解,对于整数的相反数——负数而言我们因该把四舍五入给扩展开来,让负数的变为五舍四入的办法,例如-8.4 就等于-8 而-8.5,,,-8.9 之类的就等于-9 我的数学学的也是垃圾,所以请您如果有一个权威的结果就告诉我好吗?我正好想用它来写论文,我觉得挺有意思的,谢谢了大哥

    arsaluo(热血年华) 于 2005-10-15 9:52:19

    我大学物理打指导书上还说什么四舍五入偶呢!

    不过要求不同就不同了

    大概是规定不一样吧

    trumplet(检查) 于 2005-10-15 10:53:48

    测试

    public static void main(String[] args) throws Exception {

    // TODO Auto-generated method stub

    System.out.println(-8.1 + " " + Math.round(-8.1));

    System.out.println(-8.2 + " " + Math.round(-8.2));

    System.out.println(-8.3 + " " + Math.round(-8.3));

    System.out.println(-8.4 + " " + Math.round(-8.4));

    System.out.println(-8.5 + " " + Math.round(-8.5));

    System.out.println(-8.6 + " " + Math.round(-8.6));

    System.out.println(-8.7 + " " + Math.round(-8.7));

    System.out.println(-8.8 + " " + Math.round(-8.8));

    System.out.println(-8.9 + " " + Math.round(-8.9));

    }

    运行结果:

    -8.1 -8

    -8.2 -8

    -8.3 -8

    -8.4 -8

    -8.5 -8

    -8.6 -9

    -8.7 -9

    -8.8 -9

    -8.9 -9

    BUILD SUCCESSFUL (total time: 1 second)

    trumplet(检查) 于 2005-10-15 11:07:38

    java API里说的清楚:

    Returns: the value of the argument rounded to the nearest long value.

    返回:最接近参数的long值。

    hcom(迷失在爪哇世界中) 于 2005-10-15 11:29:36

    up

    bobe2004(雨) 于 2005-10-15 14:06:01

    这应该是java和Excel对 round()方法的不同定义。

    按照java中对round()的运算法则(long)Math.floor(a + 0.5d),

    当 -8.5<a<-8.0 如 a= -8.4

    则带入公式中 返回是

    (long)Math.floor(-8.4 + 0.5d)

    =(long)Math.floor(-7.9)

    =-8

    这个运算结果是对的,

    当 a=-8.5 返回 (long)Math.floor(-8.0)=-8

    当 -9<a< -8.5 如a=-8.6 返回 (long)Math.floor(-8.1)=-9

    这些结果从java中的运算逻辑看都是对的,至于和Excel中的运算结果不同应该是二者对round()方法有不同的定义

    个人想法 ^_^!

    codearts(代码艺术) 于 2005-10-16 9:26:04

    up

    weijianyu2000(山野狂龙) 于 2005-10-16 9:29:15

    顶楼楼上

    jordan1(班君) 于 2005-10-16 16:49:39

    up

    jack1219(jack) 于 2005-10-17 16:12:58

    java中是按2进制进行计算的

    gkrong(gkrong) 于 2005-10-17 17:04:29

    感谢各位的关注。在提问之前我也有看过帮助文档,也测试过,因为不明白就有了问题一,在网上搜索相关网页后,反而更不明白了,于是就有了问题二。按 trumplet(检查)的说法,取最接近-8.5的long值,可是-8.5正好在-8和-9正中间,难道说-8更接近-8.5?

    我在ChinaJavaWorld上也发贴问了,有兴趣的朋友可以到这里看看http://bbs.chinajavaworld.com/post/view?bid=20&id=685584&sty=1&tpg=3&age=0

    问题一:Excel、SQLServer、Oracle采用"away from zero"方式Round,而Java采用"towards positive infinity"方式Round。

    问题二:是由于计算机存储空间有限,在进行十进制和二进制转换时截断了无穷的尾数。

    nilliu(刘寓) 于 2005-10-17 17:22:00

    数学上应该为 -8

Comments are closed.