Java中的长除法无法按预期工作

Java中的长除法无法按预期工作,java,long-integer,Java,Long Integer,虽然预期的答案是1000,但javac给出的答案是5。原因?表达式24*60*60*1000*1000是int类型而不是long您想要的是24L*60*60*1000*1000这是long 这就是你所拥有的 class LongDiv{ public static void main(String [] args){ final long x = 24*60*60*1000*1000; final long y = 24*60*60*1000; System.out.p

虽然预期的答案是1000,但javac给出的答案是5。原因?

表达式
24*60*60*1000*1000
int
类型而不是
long
您想要的是
24L*60*60*1000*1000
这是
long

这就是你所拥有的

class LongDiv{
public static void main(String [] args){

    final long x = 24*60*60*1000*1000;
    final long y = 24*60*60*1000;
    System.out.println(x/y);
}
}
你想要的是

final long x = (24*60*60*1000*1000) & 0xFFFFFFFF;
final long y = (24*60*60*1000) & 0xFFFFFFFF;
System.out.println(x/y);

您正在创建的长
x
不是您期望的值。它在整数范围内。要创建long,请使用:

final long x = 24L*60*60*1000*1000;
final long y = 24L*60*60*1000;
System.out.println(x/y);
您在整数范围内计算的
x
500654080
。这除以
y
(=
86400000
),得到
5.794607407…
。Java截断导致5的小数部分

通过在数字文本后添加
L
,可以告诉编译器将其编译为
long
,而不是
int
。您期望的
x
的值为
86400000000
。但是被编译为int

我们可以通过将
x
500654080
)的值截断为int来重现错误的值:

final long x = 24L*60L*60L*1000L*1000L;
final long y = 24L*60L*60L*1000L;
System.out.println(x/y);

24*60*60*1000*1000
太大,无法装入
int
和溢出。

棘手的一个

问题是24、60和1000是Java文本整数。在将值指定给x和y之前,它们会被截断以适应int值。试一试

// First correct
long x = 24L*60L*60L*1000L*1000L;
/* x = `86400000000`; */
// Now truncate
x &= 0xFFFFFFFFL; // again: don't forget the L suffix
/* x = `500654080` */
明白我的意思。快速修复方法是将文本转换为长值,如下所示:

System.out.print(x + ", " + y);
如果右操作数有文字值,则强制转换(强制)为长工作数;但在将一个长变量分配给另一个长变量的情况下,问题仍然存在,如下面给出的示例所示:

public class LongDiv{
public static void main(String [] args){

    final long x = 24l*60l*60l*1000l*1000l;
    final long y = 24l*60l*60l*1000l;
    System.out.println(x/y);
}
}
我能得到正确答案的唯一方法是将长除法转换为双打除法。很奇怪,为什么龙的分裂行为如此神秘

长除法给出的答案为零,而双除法给出的答案是正确的


我希望这能帮助其他遇到类似问题的人…

每个表达式中只有一个文本需要是
长的
。请看@Peter的答案。我知道,但我认为这是一种风格偏好。@Martijn:没有计算机,我如何计算这个值500654080!!这个问题出现在笔试中!!这是一道相当残酷的笔试题。。。我能想到的最好办法是写出每个数字的位,并用0xFFFFFFFF屏蔽它们,正如@Peter在上文中暗示的那样。@Aakash:如果问题是“为什么这个值错了?”,你可以简单地说,
x
由于忘记了
L
后缀而被构造为int。真是太棒了!没有我想的那么棘手,我想:)为了明确起见,你可以做一个
1L*24*60*60*1000*1000
。在这种情况下,你可以做
(long)24*60*60*1000*1000
什么时候会发生int->long升级?对于24或完整(初始化)结果,强制转换优先于乘法
package utils;

public class Utils {

    public static void main(String ... clps){
        Utils.longDivision();
        Utils.doubleDivision();
    }

    private static void doubleDivision(){
        double x=new Long("54321").doubleValue();
        double y=new Long("12345").doubleValue();
        double difference=x - y;
        double percentage=(difference/x)*100.00;
        System.out.println("\nDouble Division ==> X : "+x+" ; Y : "+y+" ; Difference : "+difference+" ; percentage : "+percentage+"\n");
    }

    private static void longDivision(){
        long x=new Long("54321").longValue();
        long y=new Long("12345").longValue();
        long difference=x - y;
        long percentage=(difference/x)*100L;
        System.out.println("\nLong Division ==> X : "+x+" ; Y : "+y+" ; Difference : "+difference+" ; percentage : "+percentage+"\n");
    }

}