SSブログ

SML/NJの浮動小数点数の不審な挙動(非正規数に対するReal.toManExp) [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


うーん…
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。