JuliaでRationalは危ないかも
repl.itでJulia(ver 1.3.1)を触って遊んでいたら、Rationalでとんでもないことになったので書いておく。分母でオーバーフローぎりぎりを扱う可能性のある人は気をつけて。
まず、適当に以下を実行してみてほしい。aは今回の挙動に関係ないので他の数でも問題ないと思う。
a = typemax(Int64) b = typemin(Int64) println("a = typemax(Int64) = $(a)") println("b = typemin(Int64) = $(b)") println("a // b = $(a//b)") println("(a // b) * 2 = $((a // b) * 2)")
結果はこんな感じになるはず。
a = typemax(Int64) = 9223372036854775807
b = typemin(Int64) = -9223372036854775808
a // b = -9223372036854775807//-9223372036854775808
(a // b) * 2 = 9223372036854775807//4611686018427387904
見てわかると思うが、 (a//b)*2
は負になるはず。
Rational.jlを見た感じだと21行目のchecked_denで分母を正に直しているようだが、
>a = typemin(Int64)
-9223372036854775808
>-a
-9223372036854775808
からわかるように、 typemin(T<:Integer)
に対して負の単項演算は機能しない。(当たり前だけど...)
たぶん、これが原因だろう。
以上、Rational使うと 0.1 * 3 とかを誤差なしで計算できるけど安心しすぎてはダメだよって話でした。
英語ですが、Juliaのドキュメントも読みましょう。
Juliaに関するおすすめの書籍はこちら
Juliaプログラミングクックブック ―言語仕様からデータ分析、機械学習、数値計算まで
- 作者:Bogumił Kamiński,Przemysław Szufel
- 発売日: 2019/10/19
- メディア: 単行本(ソフトカバー)