昨日の Java パズラーの超ウルトラヒントを・・・
たぶん、必要ないと思うけど・・・
package jp.yucchi.infinity;
import java.util.stream.IntStream;
public class Infinity {
public static void main(String[] args) {
IntStream.range(Integer.MAX_VALUE - 3, Integer.MAX_VALUE, 2).limit(5).forEach(System.out::println);
System.out.println("***********************************");
int count = 0;
for (int i = 0; i <= Integer.MAX_VALUE; Math.addExact(0, i++)) {
count++;
if (i > Integer.MAX_VALUE - 5) {
System.out.println(i);
}
}
System.out.println(count);
}
}
このパズルは古典的なオーバーフローをとりあげてます。
IntStream.range(Integer.MAX_VALUE - 3, Integer.MAX_VALUE, 2)
この新しい構文は、
for (int i = startInclusive; i < endExclusive ; i += step) { ... }
と同じで、i += step のところでオーバーフローをおこします。
for (int i = 0; i <= Integer.MAX_VALUE; Math.addExact(0, i++)) { ... }
このループ文は一見すると Math.addExact() メソッドを利用しているので例外が出ると思ってしまいがちですが、
よ~~~く見ると引数の i++ でオーバーフローするので無限ループになってしまいます。
とても古典的で簡単なパズルでした。
これだけだと寂しいので Math.addExact() メソッドを覗いてみました。
public static int addExact(int x, int y) {
int r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("integer overflow");
}
return r;
}
なんか良く解らないけどビット演算を駆使して判定しているようですね。
なんで今頃こんなものを・・・以下自粛。(^_^;)
Hatena タグ: Java