『Java Puzzlers』とGo言語(2)
このプログラムの実行結果は、
パズル3: 長除法(Long Division)
このパズルは、2 つのlong
値を割るプログラムに関することなので、LongDivision と呼ばれます。被除数は一日が何マイクロ秒であるかを表し、除数は一日が何ミリ秒であるかを表しています。このプログラムは、何を表示しますか?public class LongDivision {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}
}
5
です。その理由は、Javaではint
型(上記の数値リテラルはすべてint
)から構成される式の演算結果の型はint
なので、上記のMICROS_PER_DAY
への代入の右辺の式の計算結果はint
に収まらずにオーバーフローが発生しているからです。その結果、小さな値となっており、実行結果が5
なのです。単純にGo言語で書いたコードは次のようになります(対比しやすいように、Go言語の命名規則には従っていません)。
このコードの実行結果は、
package main
import "fmt"
func main() {
var MICROS_PER_DAY int64 = 24 * 60 * 60 * 1000 * 1000
var MILLIS_PER_DAY int64 = 24 * 60 * 60 * 1000
fmt.Println(MICROS_PER_DAY / MILLIS_PER_DAY)
}
1000
です。その理由は、右辺の式に書かれているものはすべて定数つまり「型付けなし整数」であるため、式の演算はコンパイル時に計算されます。そして、その計算結果の値も「型付けなし整数」なのです。「型付けなし整数」の値は、型がある変数(上記の場合、
int64
のMICROS_PER_DAY
)への代入において、変数の型(int64
)の取り得る値の範囲に収まれば、コンパイルされます。収まらなければ、コンパイルエラーです。
この記事へのコメント