2013年11月24日日曜日

Lispにおける小数の精度に関して

Lispにおける小数の精度

ProjectEuler を回答中に、要求される小数の精度が12桁ある問題があって、、、具体的には問題267のことなのだが、LispCabinet の SBCL にて回答を入力、さて実行したら、桁数が足りない。どう見ても10桁ない。というわけで調べた。

数値としての表記は共通で
(仮数部)*10^(指数部) の値をあらわす
[+|-] 数字 小数点 数字 指数マーカ [+|-] 数字
仮数部 + 指数マーカ + 指数

Lispでの浮動小数型には4種類あるそうな。
  • short-float : 小精度 : 指数マーカ s, S 
  • single-float :単精度:指数マーカ f, F
  • double-float : 倍精度 : 指数マーカ d,D
  • long-float : 長精度 : 指数マーカ l,L
指定しない場合は:*read-default-float-format*シンボルに指定された型が選ばれる。また、指数マーカe,E もある。これもデフォルト型ということのようで。

REPL上の表記としては 1.3590813e9 のようになる。

実際の挙動に関して

LispCabinet : SBCL における動作
  • s,f はe とみなされる様子
  • d,l はl とみなされる様子
  • 表示される仮数の桁数は、e => 7桁、d => 17桁
    • d のとき18桁の場合もあった
    • 結果の仮数値で後ろ(?)に0しか続かない場合、0省略される
      ※後ろとは:小数の位数が大きな側のことを言いたい
  • コード上の定数にd, l を指定した数はその後の計算も小数として扱われる
基本的に整数のみで割り算・掛け算していると自動的に有理数として扱われるのがLispシステムである。どこかに小数を割り込ませるとその後の計算がすべて小数となる

参考:

Wikipedia:浮動小数点数
数と算術演算(M. Hiroi's Home Page)
CommonLispのお勉強 (S_Nayakama 氏)

注意書き

※仕様は確認していません。
※SBCL (on LispCabinet) 以外の挙動についても確認していません。
※確認するほどの元気もやる気も責任感もないのです
※適当です

一言

整数の計算は基本的に無限桁数なのに比べると、小数側のサポートはIEEEの仕様を超えることはない様子というのが不思議といえば不思議。
と思っているだけで、実際扱う方法もあるんだろうなーなどと夢想したり。
そもそも目的である問題267はアプローチが正しくなかったようで正答が出ていないので精度は問題ではなくなってしまった。

1 件のコメント: