Java浮点整数算术

时间:2016-02-13 19:36:14

标签: java floating-point

鉴于下面的代码,输出的布尔值是

A: false
B: false
C: true

当我尝试用小于65的任何东西减去V1 + V2的总和时,它就好像从不发生减法一样。如果我将原语切换为double,问题就解决了。为什么会这样?

private static final float V1 = 1076712940;
private static final float V2 = 1070770707;

public static void main(final String[] args) {
    final float y = V1 + V2;//2147483647

    System.out.println("A: ((y - 64) - 1) == (y - 65) --> "
                        + (((y - 64) - 1) == (y - 65))); /* A */
    System.out.println("B: (y > y - 64) --> " + (y > y - 64)); /* B */
    System.out.println("C: (y > y - 65) --> " + (y > y - 65)); /* C */
}

2 个答案:

答案 0 :(得分:9)

浮点数由符号位,尾数和指数表示在内存中,它们基本上是二进制分数。许多十进制数不能完全表示为二进制分数。在指数或尾数中具有附加位将允许更高的精度水平。

我相信在你的情况下,你保存的浮点数与64减去的值之间的差异不是一个足够大的变化,以具有不同的浮点表示。但是,因为double在尾数和指数中有额外的位,所以它可以更精确,并准确地表示减法。

答案 1 :(得分:1)

这会在prior answer上稍微扩展一下。

原始程序在评论中包含y为2147483647的声明。事实并非如此。由于浮点舍入,它是2147483648.该程序查看y,以及包围它的可表示数字。 BigDecimal的toString在没有科学记数法的情况下进行精确转换,对于这种情况更清楚。 BigDecimal还对具有有限长度十进制扩展的数字进行精确算术运算,包括所有有限浮点数和双数。

import java.math.BigDecimal;

public class Test {
  private static final float V1 = 1076712940;
  private static final float V2 = 1070770707;

  public static void main(String[] args) {
    final float y = V1 + V2;// 2147483647
    BigDecimal yBD = new BigDecimal(y);
    System.out.println("y = " + yBD);
    BigDecimal down = new BigDecimal(Math.nextDown(y));
    System.out.println("nextDown(y) = " + down + " diff = " + yBD.subtract(down));
    BigDecimal up = new BigDecimal(Math.nextUp(y));
    System.out.println("nextUp(y) = " + up + " diff = " + up.subtract(yBD));
    System.out.println(Float.MAX_VALUE + Float.MAX_VALUE);
  }

}

输出:

y = 2147483648
nextDown(y) = 2147483520 diff = 128
nextUp(y) = 2147483904 diff = 256
Infinity

2147483648是2的幂,所以它下面的间隙只有128,但是上面的间隙是256.减去任何小于64的东西的确切结果接近2147483648而不是任何其他可表示的数字。减去64给出了两个数字之间的精确结果,以及向2147483648的四舍五入到第八轮。减去65具有更接近2147483520的精确结果。

在评论中,您会问:“我已将V1V2切换为Float.MAX_VALUE结果已更改A:true B:false C:false您对此有何看法? ?“

我的第一个想法是,通过我的程序的最后一个输出证实,“这使得y无限。”在无穷大中添加或减去有限数不会改变其值。无穷大等于它自己。

一般来说,如果你直接查看所涉及的数字,而不是仅仅查看测试结果和涉及它们的比较,就会更容易看到发生了什么。