SML/NJの浮動小数点数の不審な挙動(非正規数に対するReal.toManExp) [SML]
またSML/NJの浮動小数点数の処理で怪しいのを見つけてしまった。
SMLではReal.minPosという値が定義されている。これはIEEE754で表現できる0の隣の一番小さい正数なのだが、浮動小数点の世界では非正規化数というカテゴリに入る。(簡潔に説明できないのでWikipediaなどを参照ください)
Real.toManExpという関数はrealを仮数部と指数部に分ける関数である。
この2つを組み合わせるとどうなるか。
SML/NJ
Poly/ML
SML#
MLton
またSML/NJだけ仲間外れになった。SML/NJ以外のほうが明らかにわかりやすいんだけどtoManExpは単にmanに基数のexp乗をかけると元の数になるって言っているだけだから、そういうのが複数あるというだけかもしれない。
次にこういうのを書く。
どうかな…
SML#
SML/NJ
うーん…
SMLではReal.minPosという値が定義されている。これはIEEE754で表現できる0の隣の一番小さい正数なのだが、浮動小数点の世界では非正規化数というカテゴリに入る。(簡潔に説明できないのでWikipediaなどを参照ください)
Real.toManExpという関数はrealを仮数部と指数部に分ける関数である。
この2つを組み合わせるとどうなるか。
fun main () = let val {man=man, exp=exp} = Real.toManExp Real.minPos in print ("man=" ^ Real.toString man ^ "\n"); print ("exp=" ^ Int.toString exp ^ "\n") end val _ = main ()
SML/NJ
Standard ML of New Jersey v110.76 [built: Sat Sep 7 21:22:34 2013] - use "minpos.sml"; [opening minpos.sml] [autoloading] [library $SMLNJ-BASIS/basis.cm is stable] [autoloading done] man=2.22044604925E~16 exp=~1022 val main = fn : unit -> unit val it = () : unit
Poly/ML
> use "minpos.sml"; man=0.5 exp=~1073 val main = fn : unit -> unit val it = () : unit
SML#
# use "minpos.sml"; man=0.5 exp=~1073 val main = fn : unit -> unit
MLton
man=0.5 exp=~1073
またSML/NJだけ仲間外れになった。SML/NJ以外のほうが明らかにわかりやすいんだけどtoManExpは単にmanに基数のexp乗をかけると元の数になるって言っているだけだから、そういうのが複数あるというだけかもしれない。
次にこういうのを書く。
fun f r = let val {man=man, exp=exp} = Real.toManExp r val r' = man * (Math.pow (2.0, Real.fromInt exp)) in Real.== (r, r') end val eq = f Real.minPos
どうかな…
Poly/ML 5.2 Release > use "minpos2.sml"; val eq = true : bool val f = fn : Real.real -> bool val it = () : unit >
SML#
# use "minpos2.sml"; val eq = true : bool val f = fn : real -> bool
SML/NJ
Standard ML of New Jersey v110.76 [built: Sat Sep 7 21:22:34 2013] - use "minpos2.sml"; [opening minpos2.sml] [autoloading] [library $SMLNJ-BASIS/basis.cm is stable] [autoloading done] val f = fn : real -> bool val eq = false : bool val it = () : unit
うーん…
2014-01-21 00:56
nice!(0)
コメント(0)
トラックバック(0)
コメント 0