『Java Puzzlers』とGo言語(2) [golang]
パズル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
)の取り得る値の範囲に収まれば、コンパイルされます。収まらなければ、コンパイルエラーです。2017-11-29 06:56
コメント(0)
コメント 0