JavaでのintへのキャストとintValue()メソッドの違い

整数に変換する必要があるlong値があります。私がキャスティングを使用するとき、時々整数値はマイナスの値を与えます、これは予想されていません。しかし、<�コード> Long </コード>で<�コード> intValue()</コード>メソッドを使用すると、期待通りの結果が得られます。

キャストと<�コード> intValue </コード>()メソッドの使用の違いを知りたい

  1. Casting Example

    <�コード>int days = (int) ((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24));</コード>

  2. intValue Example

    <�コード>int days = ((Long) ((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24))).intValue();</コード>

編集:コメントで提案されているようにオーバーフローなしでマイナスの値を表示するための例をもっと詳しく説明キャストする前の結果は27です。キャストすると、値は-22になります。しかし、intValueメソッドを使用した場合、結果は27です。

コード

<�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������

����

<��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
4
念のために言っておきますが、 "fromDate"が "toDate"より "小さい"ことを確認するために、コードをチェックしてください。
追加された 著者 GhostCat,
ありがとうございました。それに従ってコーディングします。ありがとうございました。
追加された 著者 Buddhika Ariyaratne,
ごめんなさい。それが最良の答えです。受け入れました。
追加された 著者 Buddhika Ariyaratne,
ごめんなさい。それが最良の答えです。受け入れました。
追加された 著者 Buddhika Ariyaratne,
それは日付計算のせいではなく、キャストから来ています。確認にはSystem.out.printlnを使用しました。
追加された 著者 Buddhika Ariyaratne,
それは日付計算のせいではなく、キャストから来ています。確認にはSystem.out.printlnを使用しました。
追加された 著者 Buddhika Ariyaratne,
Javaのバージョンは1.7.0_71です
追加された 著者 Buddhika Ariyaratne,
Javaのバージョンは1.7.0_71です
追加された 著者 Buddhika Ariyaratne,
ありがとうございました。それに従ってコーディングします。ありがとうございました。
追加された 著者 Buddhika Ariyaratne,
@BuddhikaAriyaratneはまだオーバーフローから保護することについての言及を見つけることができないので、どちらにしてもチェックしないことをお勧めしません。私は私が見つけたいくつかのより多くの解決策のために私の答えを更新しています
追加された 著者 matrixanomaly,
@BuddhikaAriyaratneはまだオーバーフローから保護することについての言及を見つけることができないので、どちらにしてもチェックしないことをお勧めしません。私は私が見つけたいくつかのより多くの解決策のために私の答えを更新しています
追加された 著者 matrixanomaly,
@BuddhikaAriyaratneがあなたの更新されたテストを見たところです...興味深い、私はオーバーフローを避けるためにjavadocでintValueの実装を見ていません、それはオーバーフローが起こるかもしれないか未定義の問題かもしれません?ところで、Javaのどのバージョン
追加された 著者 matrixanomaly,
@BuddhikaAriyaratneがあなたの更新されたテストを見たところです...興味深い、私はオーバーフローを避けるためにjavadocでintValueの実装を見ていません、それはオーバーフローが起こるかもしれないか未定義の問題かもしれません?ところで、Javaのどのバージョン
追加された 著者 matrixanomaly,
唯一の違いは、最初のものは(int)で、他のものは(int)(Long)です。結果を変えてはいけません
追加された 著者 Oskar Kjellin,
唯一の違いは、最初のものは(int)で、他のものは(int)(Long)です。結果を変えてはいけません
追加された 著者 Oskar Kjellin,
最初の例は、オブジェクトの作成がないため、高速になるはずです(longからintへのキャストは1 CPUサイクルになるはずです)。 2番目の例では、「オートボクシング」のため、基本的に新しいオブジェクトを作成しています。これは、「new Long(((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24)))。intValue()」と同じです。
追加された 著者 BretC,
最初の例は、オブジェクトの作成がないため、高速になるはずです(longからintへのキャストは1 CPUサイクルになるはずです)。 2番目の例では、「オートボクシング」のため、基本的に新しいオブジェクトを作成しています。これは、「new Long(((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24)))。intValue()」と同じです。
追加された 著者 BretC,
int キャストは元の投稿と、追加した新しい編集では異なります。元: int days =(int)((toDate.getTime() - fromDate.getTime())/( 1000 * 60 * 60 * 24)); 編集: System.out.println( "((int)(nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()))/(1000 * 60 * 60 * 24))= "+((int)(nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24)));
追加された 著者 Mecon,
int キャストは元の投稿と、追加した新しい編集では異なります。元: int days =(int)((toDate.getTime() - fromDate.getTime())/( 1000 * 60 * 60 * 24)); 編集: System.out.println( "((int)(nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()))/(1000 * 60 * 60 * 24))= "+((int)(nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24)));
追加された 著者 Mecon,
私の答えは受け入れられなかった...しかしそれは本当に正しい答えでした。 2つの方法に違いはありません。
追加された 著者 Mecon,
私の答えは受け入れられなかった...しかしそれは本当に正しい答えでした。 2つの方法に違いはありません。
追加された 著者 Mecon,
あなたは TimeUnit を使うべきです
追加された 著者 user180100,
あなたは TimeUnit を使うべきです
追加された 著者 user180100,

8 答え

あなたはint overflowを打っているかもしれません。 toDate.getTime()fromDate.getTime()の差が2147億を超える場合(つまり Integer.MAX_VALUE )、整数で表現することはできません。ラップして最小値に変更するだけです。 Integer.MAX_VALUE + 100 はマイナスの結果になります。

オーバーフローせずに int にキャストするのに十分な大きさになるまで、最初にすべての操作をlongで実行する必要があります。私はあなたの両方の例が正しいと思います、最初のものは他より確かにはるかに明確です。

また、 1000 * 60 * 60 * 24 のような式は整数であり、オーバーフローする可能性もあります。たとえば、1か月のミリ秒数は 31 * 24 * 3600 * 1000 ですが、このように書くと -1616567296 が返されます。

EDIT: Let me explain the output you have attached in your edit :

Info: nextDeliveryDate.getTime() - expectedDeliveryDate.getTime() = 2332800000
Info: (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24) = 27
Info: ((int) (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24)) = -22
Info: ((Long) ((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24))).intValue() = 27

nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()x としても参照します。そのため、 long x = 2332800000 として宣言できます(intを宣言すると、4バイトに収めるには大きすぎるのでコンパイルエラーが発生します)。

最初の行には、 x/something があります。 something はintであり、xはlongです。したがって、 something はlongに変換されます。最終結果は長いです。

2行目には((int)x)/ something があるので、長い2332800000は-1962167296を与える整数にキャストされ、 -1962167296/something になります。

最後の行には(Long)(x/something)がありますが、これは最初のものと事実上同じです。

5
追加された
詳細を表示するようにコードを編集しました。例では、期待されるint値が27の場合が示されています。最終結果にオーバーフローはありません。
追加された 著者 Buddhika Ariyaratne,
ありがとうございました。この数は、オーバーフローなしにintにキャストするのに十分小さいことを確認してください。それから私はいくつかの追加行を使用しなければならないかもしれません。しかし、intValueを使用すれば、心配する必要はないようです。
追加された 著者 Buddhika Ariyaratne,
あなたの質問に編集を含めるように回答を編集しました
追加された 著者 Jaroslaw Pawlak,

あなたはint overflowを打っているかもしれません。 toDate.getTime()fromDate.getTime()の差が2147億を超える場合(つまり Integer.MAX_VALUE )、整数で表現することはできません。ラップして最小値に変更するだけです。 Integer.MAX_VALUE + 100 はマイナスの結果になります。

オーバーフローせずに int にキャストするのに十分な大きさになるまで、最初にすべての操作をlongで実行する必要があります。私はあなたの両方の例が正しいと思います、最初のものは他より確かにはるかに明確です。

また、 1000 * 60 * 60 * 24 のような式は整数であり、オーバーフローする可能性もあります。たとえば、1か月のミリ秒数は 31 * 24 * 3600 * 1000 ですが、このように書くと -1616567296 が返されます。

EDIT: Let me explain the output you have attached in your edit :

Info: nextDeliveryDate.getTime() - expectedDeliveryDate.getTime() = 2332800000
Info: (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24) = 27
Info: ((int) (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24)) = -22
Info: ((Long) ((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24))).intValue() = 27

nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()x としても参照します。そのため、 long x = 2332800000 として宣言できます(intを宣言すると、4バイトに収めるには大きすぎるのでコンパイルエラーが発生します)。

最初の行には、 x/something があります。 something はintであり、xはlongです。したがって、 something はlongに変換されます。最終結果は長いです。

2行目には((int)x)/ something があるので、長い2332800000は-1962167296を与える整数にキャストされ、 -1962167296/something になります。

最後の行には(Long)(x/something)がありますが、これは最初のものと事実上同じです。

5
追加された
詳細を表示するようにコードを編集しました。例では、期待されるint値が27の場合が示されています。最終結果にオーバーフローはありません。
追加された 著者 Buddhika Ariyaratne,
ありがとうございました。この数は、オーバーフローなしにintにキャストするのに十分小さいことを確認してください。それから私はいくつかの追加行を使用しなければならないかもしれません。しかし、intValueを使用すれば、心配する必要はないようです。
追加された 著者 Buddhika Ariyaratne,
あなたの質問に編集を含めるように回答を編集しました
追加された 著者 Jaroslaw Pawlak,

Long.intValue()メソッドの動作は次のとおりです。

public int intValue() {
    return (int)value;
}

これら2つの行の間の制御の流れに問題があります。

あなたは以下のこのテストを試すことができます:

Calendar now = Calendar.getInstance();
Date fromDate = now.getTime();
now.add(Calendar.YEAR, 10);
Date toDate = now.getTime();

System.out.println("line 0: " + (toDate.getTime() - fromDate.getTime()));
System.out.println("line 1: " + (int)(toDate.getTime() - fromDate.getTime()));
System.out.println("line 2: " + new Long((toDate.getTime() - fromDate.getTime())).intValue());

int days = (int) ((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24));

System.out.println("line 3: " + days);

days = ((Long) ((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24))).intValue();

System.out.println("line 4: " + days);
3
追加された
あなたの主張を理解することはできません。ごめんなさい
追加された 著者 Buddhika Ariyaratne,
あなたは正しいです。キャストメソッドとintValueメソッドに違いはありません。質問を更新します。
追加された 著者 Buddhika Ariyaratne,
結果は異なります。出力を使用して違いを表示し、それを編集として追加しました。
追加された 著者 Buddhika Ariyaratne,
このように最後の2番目の行で編集を再試行します。 "+((int)((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24)))););
追加された 著者 Mecon,
前回のEditで異なる値を取得したのは、(int)操作が減算部分のみに適用されていたためです。減算 - WITH - divisionの結果に適用する必要があります。
追加された 著者 Mecon,
私のポイントは、2つの操作が(int)Long.intValue()を参照しているということです。
追加された 著者 Mecon,
私はあなたの編集をチェックしたところです。最後の2行は元の投稿とは異なります。最後から2行目では、「減算」を int キャストしてから分割しています。 "減算"の結果は非常に大きい数なので、オーバーフローを引き起こします。しかし最後の行では、変電所と部門の組み合わせに long.intValue を適用しています。その値は非常に小さいので(27)、したがってオーバーフローを引き起こすことはありません。
追加された 著者 Mecon,

Long.intValue()メソッドの動作は次のとおりです。

public int intValue() {
    return (int)value;
}

これら2つの行の間の制御の流れに問題があります。

あなたは以下のこのテストを試すことができます:

Calendar now = Calendar.getInstance();
Date fromDate = now.getTime();
now.add(Calendar.YEAR, 10);
Date toDate = now.getTime();

System.out.println("line 0: " + (toDate.getTime() - fromDate.getTime()));
System.out.println("line 1: " + (int)(toDate.getTime() - fromDate.getTime()));
System.out.println("line 2: " + new Long((toDate.getTime() - fromDate.getTime())).intValue());

int days = (int) ((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24));

System.out.println("line 3: " + days);

days = ((Long) ((toDate.getTime() - fromDate.getTime())/(1000 * 60 * 60 * 24))).intValue();

System.out.println("line 4: " + days);
3
追加された
あなたは正しいです。キャストメソッドとintValueメソッドに違いはありません。質問を更新します。
追加された 著者 Buddhika Ariyaratne,
結果は異なります。出力を使用して違いを表示し、それを編集として追加しました。
追加された 著者 Buddhika Ariyaratne,
あなたの主張を理解することはできません。ごめんなさい
追加された 著者 Buddhika Ariyaratne,
前回のEditで異なる値を取得したのは、(int)操作が減算部分のみに適用されていたためです。減算 - WITH - divisionの結果に適用する必要があります。
追加された 著者 Mecon,
このように最後の2番目の行で編集を再試行します。 "+((int)((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime())/(1000 * 60 * 60 * 24)))););
追加された 著者 Mecon,
私のポイントは、2つの操作が(int)Long.intValue()を参照しているということです。
追加された 著者 Mecon,
私はあなたの編集をチェックしたところです。最後の2行は元の投稿とは異なります。最後から2行目では、「減算」を int キャストしてから分割しています。 "減算"の結果は非常に大きい数なので、オーバーフローを引き起こします。しかし最後の行では、変電所と部門の組み合わせに long.intValue を適用しています。その値は非常に小さいので(27)、したがってオーバーフローを引き起こすことはありません。
追加された 著者 Mecon,

Firstly, to explain a little about the difference between casting to int and IntValue() method in Java.

IntValue() is a method in the Integer class (and other wrapper classes).

IntValueが行うことは、整数を取得し、それを int 型として返すことです。

Note that int is an primitive datatype and Integer is a class that holds this datatype. It's like a wrapper, because there are data structures that cannot hold primitive datatypes. See this SO question for more info

基本的に:

intを整数に変換することをボクシングと呼びます。

     

整数をintに変換することをボックス化解除と呼びます。

SO質問で述べたように私はリンクしました。

However, as for your example, this is a little different because of the types involved. The difference is that you perform all operations as a Long datatype, which holds a lot more numbers than an int first, for accuracy, then only convert it to an int. So your IntValue() method is from the long datatype, which Java7 docs mention of it's use. Basically it just changes it from a long to an int, which still can cause overflows.

Long は、プリミティブデータ型 long のラッパークラスです(プリミティブデータ型にはIntValue()メソッドがありません)

So the difference in values you get may be because when you did the simple cast from Long -> int primitive datatypes, there wasn't an overflow.

変更しないように非常に大きな数でコードをテストすることをお勧めします(日付とは異なり、時間は取得するたびに異なります)

オーバーフロー問題を解決する

このSO質問を参照してください。

私が提案するもう一つの方法は、使用のためにそれをintにキャストバックする前に、最初に精度を下げる(それゆえあなたは精度を失う)安全な十分な値(そして正確に十分な値)にすることです。

Or, use BigIntegers, which are immutable arbitrary-precision integers. see the the documentation on this class and this SO Q&A on how to use it. It is definitely going to add complexity to the code as they are immutable.

This other SO question has good solutions that give nice methods on detecting overflow in ints and longs which I also recommend as well.

2
追加された
説明をありがとうございました。将来的にコード内のエラーを回避するために、それらは私にとって非常に貴重です。しかし、Meconと他の人が指摘したように、私の編集したコードでは、castメソッドとintValueメソッドの使用方法に違いがあります。 intValueメソッドのキャストと使用に本質的な違いはありません。
追加された 著者 Buddhika Ariyaratne,

Firstly, to explain a little about the difference between casting to int and IntValue() method in Java.

IntValue() is a method in the Integer class (and other wrapper classes).

IntValueが行うことは、整数を取得し、それを int 型として返すことです。

Note that int is an primitive datatype and Integer is a class that holds this datatype. It's like a wrapper, because there are data structures that cannot hold primitive datatypes. See this SO question for more info

基本的に:

intを整数に変換することをボクシングと呼びます。

     

整数をintに変換することをボックス化解除と呼びます。

SO質問で述べたように私はリンクしました。

However, as for your example, this is a little different because of the types involved. The difference is that you perform all operations as a Long datatype, which holds a lot more numbers than an int first, for accuracy, then only convert it to an int. So your IntValue() method is from the long datatype, which Java7 docs mention of it's use. Basically it just changes it from a long to an int, which still can cause overflows.

Long は、プリミティブデータ型 long のラッパークラスです(プリミティブデータ型にはIntValue()メソッドがありません)

So the difference in values you get may be because when you did the simple cast from Long -> int primitive datatypes, there wasn't an overflow.

変更しないように非常に大きな数でコードをテストすることをお勧めします(日付とは異なり、時間は取得するたびに異なります)

オーバーフロー問題を解決する

このSO質問を参照してください。

私が提案するもう一つの方法は、使用のためにそれをintにキャストバックする前に、最初に精度を下げる(それゆえあなたは精度を失う)安全な十分な値(そして正確に十分な値)にすることです。

Or, use BigIntegers, which are immutable arbitrary-precision integers. see the the documentation on this class and this SO Q&A on how to use it. It is definitely going to add complexity to the code as they are immutable.

This other SO question has good solutions that give nice methods on detecting overflow in ints and longs which I also recommend as well.

2
追加された
説明をありがとうございました。将来的にコード内のエラーを回避するために、それらは私にとって非常に貴重です。しかし、Meconと他の人が指摘したように、私の編集したコードでは、castメソッドとintValueメソッドの使用方法に違いがあります。 intValueメソッドのキャストと使用に本質的な違いはありません。
追加された 著者 Buddhika Ariyaratne,

違いはありません、このコード

public static void main(String[] args) {
    System.out.println((int) (21470000000l));
    System.out.println((int) ((Long)21470000000l).intValue());
}

この出力があります:

-4836480
-4836480

したがって、 toDatefromDate には異なる値があります。

値が整数のMAXを超えると、「期待どおりの」結果が得られません。

2
追加された
違いがあります。編集したコードを参照してください。
追加された 著者 Buddhika Ariyaratne,

違いはありません、このコード

public static void main(String[] args) {
    System.out.println((int) (21470000000l));
    System.out.println((int) ((Long)21470000000l).intValue());
}

この出力があります:

-4836480
-4836480

したがって、 toDatefromDate には異なる値があります。

値が整数のMAXを超えると、「期待どおりの」結果が得られません。

2
追加された
違いがあります。編集したコードを参照してください。
追加された 著者 Buddhika Ariyaratne,