【问题标题】:int to long assignmentint 到长赋值
【发布时间】:2014-07-15 10:17:55
【问题描述】:

我一直在尝试这种 int 和 long 转换,我尝试将 int 变量分配给 long 变量。代码如下:

public static void main(String []args){
    int i = 1024;
    long j = i;
    long k = i*i*i*i;
    System.out.println("j= " +j+ ", k= " +k);
}

因此,在打印 j 时,它只给出了 1024 的输出。但是在打印k 时,它显示了溢出(k=0)。我通过使用这种技术解决了这个问题,我将每个i 显式转换为long。即

public static void main(String []args){
    int i = 1024;
    long j = i;
    long k = ((long)i)*((long)i)*((long)i)*((long)i);
    System.out.println("j= " +j+ ", k= " +k);
}

现在,它显示了jk 的正确值。 所以,我想知道为什么需要在第二种情况下转换int 而不是在第一种情况下。 k,作为 long 可以在这个繁重的分配之后保留这个值。但是,为什么没有正确分配呢?

【问题讨论】:

  • 先将i 转换为 long 就足够了
  • 您发现的缺陷模式——可能溢出的整数乘法“为时已晚”转换为更大的类型——在 C# 和 Java 中都比较常见;我们发现每百万行代码分析超过 5 个实例。具有相似发现率的相关缺陷是两个整数的除法和“为时已晚”转换为双精度数;人们常常惊讶于三百除以五百并分配给一个双倍是零,而不是 0.6。

标签: java int long-integer


【解决方案1】:

原因是你的线

long k = i*i*i*i;

可以认为是

long k = ((i*i)*i)*i;

或者...

int k1 = i*i;
int k2 = k1*i;
int k3 = k2*i;
long k = k3;

因此,当任何kn 溢出时,您都会收到错误消息。

当你做你的演员时,你显然通过总是将longs 相乘来规避这个问题。

当然,对初始程序最简单的修改是立即将i 定义为long,而不是int

long i = 1024L;

【讨论】:

  • @dav_i , k3 会溢出,因为它是int 变量,必须是long
【解决方案2】:

这个问题是基于不同的类型使用不同的内存量。 int和long都是Integers,区别在于int是4字节,而long 为 8 个字节

让我们稍微修改一下你的代码:

public class Test {


  public static void main(String []args){
        int i = 1024;
        long j = i;
        long k = i*i*i;

        System.out.println("My multipliers are of type int:");
        System.out.println("j= " +j+ ", k= " +k);           
        System.out.println("Is k less than Integer.MAX_VALUE: "  + (k < Integer.MAX_VALUE? "YES" : "NO"));
        k = i*i*i*i;
        System.out.println("j= " +j+ ", k= " +k);

        //now multiplying with j instead of i
        System.out.println("\nNow Im working with a long type:");
        k = j*j*j;
        System.out.println("j= " +j+ ", k= " +k);           
        System.out.println("Is k less than Integer.MAX_VALUE: "  + (k < Integer.MAX_VALUE? "YES" : "NO"));
        k = j*j*j*j;
        System.out.println("j= " +j+ ", k= " +k);
        System.out.println("Is k less than Integer.MAX_VALUE: "  + (k < Integer.MAX_VALUE? "YES" : "NO"));
        k = j*j*j*j;

     }

}

上面的代码显示,当你将 i 乘以 3 时,结果是一个小于 Integer.MAX_VALUE(即 2147483647)的值,当你将它乘以 4 时,结果是 0,因为没有足够的地方在乘法器的可怜的 4 个字节中。 :) 但是您可以看到,当乘数(右侧,j)为 long 类型时,会打印正确的值,而最后一次打印显示语句 k

【讨论】:

  • 感谢您的回复。我很感激。
【解决方案3】:

i*i*i*i 是一个全整数乘法,因此结果仅为整数(在您的情况下溢出)。对于 long 结果,您只需要将其中一个转换为 long 就足够了

long k = ((long)i)*i*i*i;

【讨论】:

  • 关联性在这里发挥作用吗?我的意思是,如果它是右关联的,那么,如果它在到达 (long i) 之前越过 integer_max_value,它会在你的情况下再次显示溢出。
  • 试试@ShashishChandra
  • 我试过了,多亏了你,它成功了。我只是问,这里有关联性的作用吗?
  • 因此,它保持关联,并且只能以这种方式工作。感谢您的回复,非常感谢。
  • 是的,在这种情况下它会起作用。因为与i 的第四次乘法超出了Integer.MaxValue。所以这两种方法都行得通。但是,如果您选择更高的 i 以使三个乘法超出 Integer.MaxValue,您将看到该行为。
【解决方案4】:

首先 i 的值是一个 int 并且发生整数乘法,i*i*i*i 结果是整数,因此 integer overflow.

在第二种情况下,您明确告诉/使结果为long

【讨论】:

  • 感谢您的回复。这真的很有帮助。欣赏它。
【解决方案5】:

1099511627776 这是乘法的结果是 &gt;Integer.MAX_VALUE 因为它是整数乘法所以在 i*i*i 之后值将是 1073741824 但在与 1024 相乘后它变得超出范围导致 integer overflow 和 k将是 0。

  • 您可以将i 之一转换为long
  • 乘以1L (1L*i*i*i*i) 但不是i*i*i*i*1L
  • 您还可以将i*i*i 分配给long,然后与i 相乘,就像这样long k =(k=i*i*i)*i;

【讨论】:

  • 感谢您的回复。我很感激。
猜你喜欢
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
相关资源
最近更新 更多