Java双到长转换错误之谜

Java双到长转换错误之谜,java,Java,谁能给我解释一下吗 public static void main(String[] args) { long a = 0; long b = 0; Random r = ThreadLocalRandom.current(); for (int i = 0; i < 1000; i++) { double d = r.nextDouble()*(r.nextBoolean() ? 1.0 : -1.0); a

谁能给我解释一下吗

    public static void main(String[] args) {

    long a = 0;
    long b = 0;
    Random r = ThreadLocalRandom.current();

    for (int i = 0; i < 1000; i++) {
        double d = r.nextDouble()*(r.nextBoolean() ? 1.0 : -1.0);

        a += d*100;
        b += (long)(100*d);
        //System.out.println(a + " " + b + " " + d);

    }

    System.out.println(a);
    System.out.println(b);
    }
publicstaticvoidmain(字符串[]args){
长a=0;
长b=0;
Random r=ThreadLocalRandom.current();
对于(int i=0;i<1000;i++){
双d=r.nextDouble()*(r.nextBoolean()?1.0:-1.0);
a+=d*100;
b+=(长)(100*d);
//系统输出打印项次(a+“”+b+“”+d);
}
系统输出打印项次(a);
系统输出打印ln(b);
}
为什么是a!=b在这个循环的末尾。这是矩阵中的小故障吗?如果我去掉“d”的随机符号,那么a==b。为什么?

根据
+=
的规定如下:

形式为E1 op=E2的复合赋值表达式等价于E1=(T)((E1)op(E2)),其中T是E1的类型,但E1仅计算一次

这意味着你的两个陈述

  a += d*100;
  b += (long)(100*d);
基本相当于

  a = (long) (a + d*100);
  b = (long) (b + (long)(100*d));
a
的情况下,加法介于
long
值和
double
值之间,因此整个计算将在
double
域中完成

b
的情况下,加法的两部分都是
long
值,因此计算将使用
long
数学


由于
long
double
具有不同的值范围,因此结果可能会有所不同。

这里发生的是四舍五入

您的作业:

a += d*100
b += (long)(100*d);
将按以下方式执行:

a = (long)(a + d * 100);
b = b + (long)(100 * d);
在一个循环之后,当a和b为正而d为负时,a和b可能不同,反之亦然。将d*100添加到a时,您正在添加精确值(例如-1.1),而对于b,它将首先四舍五入到-1。 让我们举个例子。在循环开始时,我们将获得以下值:

a = b = 1024
d = -0.178
单次运行的最终结果将是:

a = (long)(1024-17.8) = (long)(1006.2) = 1006
b = 1024-(long)17.8 = 1024-17 = 1007

这对我来说仍然没有意义。如果我们对不同的原语超出值范围,这是有意义的。但如果我们启动a&b=231和d=-0.2779593247777002,那么a=>203和b=>204显然没有超出范围。但它给了我另一个想法,它可能是一个舍入误差?不认为舍入错误会导致这种现象……考虑<代码>(long)(1 +(-0.1))< /> > vs>代码> 1L+((long)-0.1)< /代码>,这似乎是一个“舍入问题”,在每次迭代后记录总数时值得注意。第一个不匹配出现第一个负数,
d=-0.5078606970338732
a
减少了
51
a+=d*100
),而
b
减少了
50
b+=(long)(100*d)
)…结论:
long
double
使用不同的“舍入规则”关于负数。。。证明:…某处:“…如果升级类型为int或long,则执行整数运算。如果升级类型为float或double,则执行浮点运算…”大家干得好!问得好!另一方面,如果右边是浮点数,我绝对不会想到a | b会被转换成浮点数。我认为这很不现实,但我猜它在规范中的某个地方。