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はアプローチが正しくなかったようで正答が出ていないので精度は問題ではなくなってしまった。

2013年11月16日土曜日

mapcar と計算で突破する Project Euler

Lisp の勉強にと思ってはじめた ProjectEulerが面白すぎる

有名な「プログラミング問題サイト」は、多くがLispに対応していない。
  • ×:PKU Judge System -> C, C++, Java だっけ
  • ×:AOJ Judge System -> C, C++, Java,, だっけ???
  • ×:Top Coder -> Java, C++, C# は知っている
  • ○:shinichiro_h さんのゴルフ場 -> 言語のたまり場状態
  • ×:Code Golf 本家 -> たしかダメ, Perl, Python, Ruby だっけ?
有名、は有名だろう、考えてみたら自分があんまりサイトを知らないだけのような気がしてきたがまあいいや

ProjectEuler の特殊で面白い点は
  • 目的は「結果」であって「過程」は各回答者の自由
    • 公式にも「WEB探して答えを見つけちゃうこともあるだろうけど、
      でも、あなたはそれでいいの?」と書いてある。
      スタンスがわかる文書である。
  • 問題がよく作りこまれている
    • 主観ではあるが。
  • 回答は「答えの数字」であって「プログラム」でも「実行結果」でもない
  • 正答者のみが閲覧可能な回答スレッドでは、コードの公開がされているが
    簡単な問題でも思いもよらない方法があったり、もっときれいなコードにあったりと
    勉強になる
    • 答えだけならいくつかぐぐれば見つかることは確認済みだけれども。
一口に言って、プログラミング自体を勉強したいなら、圧倒的にTopCoderが選択肢ではある。本番環境だし、言語も今はやっているものだし。競争相手も多いし、問題も良く練られていると聞いているし、なにより「Challange」システムがコードの向上につながるだろうし。
けれど「解けるとわかっているものをあの手この手で解く行為」を楽しめるという点にはまった。自分にはわからないけど、確かに解ける方法がある、でもわからない!わくわく感がある。

問題はすべて英語なので、その点ハードルは高いかもしれないが、、、有志の日本語訳ページもあるので、どうしてもという場合はどうぞ。あと、エキサイト翻訳やGoogle翻訳でも多くの問題は大丈夫と思うぞ。一番問題なのは、翻訳ではなくて問題自体の難しさだし。

ああ、面白い。

最後に、雑感。
  • 多く使われている(使っていると主張されている)言語が統計で見られる
    • Mathematicaは知っていたが、PARI/GP , Sage, APL/J/K、、現代はすごいな!
    • Spread Sheet  vs Pencil/Peper :回答力では SpreadSheetが勝る様子
    • Lisp !!!
  • 今のところ「使った」アイデアは
    • バックトラック
    • どうしても解けなくて遺伝的アルゴリズム => でも解けない orz
  • 言語の導入にも面白そうだ
    • 簡単な問題であれば「答えさえわかればよい」ので。
      簡単な計算がプログラミングできますか?ということ。
      これがやってみると難しいものです。
    • ただし、多倍長整数への親和性はなるたけほしいかも。
      • その点Lispは「組み込みで対応」なのが壁の低さにつながった
      • C/C++だとライブラリないし自作必須だからなあ、、、。