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

发布于 11-25 10:31 字数 234 浏览 1 评论 0原文

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);
}
}

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

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);
}
}

although the expected answer is 1000, but the javac gives it as 5. Reason?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

雨落星ぅ辰2024-12-02 10:31:02

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

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

您在整数范围内计算出的 x5006540​​80。除以 y (= 86400000),结果为 5.794607407407407...。 Java 会截断小数部分,从而导致 5。

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

我们可以通过将 x (5006540​​80) 截断为 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` */

The long x you are creating isn't the value you expected. It is in the integer range. To create longs, use:

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

The x you computed, in the integer range, was 500654080. This divided by the y ( = 86400000), results in 5.794607407407407.... Java truncates the decimal part which causes the 5.

By adding an L after the number literal, you tell the compiler to compile it as a long instead of an int. The value for x you expected is 86400000000. But is was compiled as an int.

We can reproduce the wrong value for x (500654080) by truncating it to an 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` */
浅忆2024-12-02 10:31:02

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

这就是你所拥有的。

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

你想要的是

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

The expressions 24*60*60*1000*1000 is an int type not a long What you want is 24L*60*60*1000*1000 which is long

This is what you have.

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

what you want is

final long x = 24L*60*60*1000*1000;
final long y = 24L*60*60*1000;
System.out.println(x/y);
三生一梦2024-12-02 10:31:02

如果右操作数是字面值,则强制转换为长工作;但如果将一个长变量分配给另一个变量,问题仍然存在,如下面给出的示例所示:

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");
    }

}

我能得到正确答案的唯一方法是将长整除法转换为双精度除法。很奇怪为什么长数除法的表现如此神秘。

longDivision 给出的答案为零,而 doubleDivision 给出的答案是正确的。

我希望这可以帮助遇到类似问题的其他人...

casting (forcing) to long works in case of literal values for the right operand; but the problem persists in case of assigning one long variable to another, as in the below given example:

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");
    }

}

The only way i could get proper answer is by converting the division of longs into division of doubles. It is very strange why division of longs behaves in such mysterious manner.

longDivision gives the answer as zero whereas the doubleDivision gives the correct answer.

I hope this helps others who encountered similar issues...

一袭白衣梦中忆2024-12-02 10:31:02

24*60*60*1000*1000 太大,无法放入 int 中并溢出。

24*60*60*1000*1000 is too large to fit into an int and overflows.

岛徒2024-12-02 10:31:02

棘手的一个!

问题是 24、60 和 1000 是 Java 文字 int。在将值分配给 x 和 y 之前,它们会被截断以适合 int 值。试着

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);
}
}

Tricky one!

The issue is that 24, 60, and 1000 are Java literal ints. Before the values are assigned to x and y, they are truncated to fit in int values. Try

System.out.print(x + ", " + y);

to see exactly what I mean. The quick fix is to make your literals into long values like so:

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);
}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文