パスワードを忘れた? アカウント作成
10813426 journal
Ruby

t-nissieの日記: 【電脳】Ruby 2.1の複素数の新機能の-1.0-0.0i→(-1.0+0.0i)と『浮動小数点演算について計算機科学者は何を知っておくべきか』の書誌情報 2

日記 by t-nissie

複素数の定数は、Fortranでは次のように(-1.0d0,-0.0d0)などと書きます。

$ cat complextest.f
program complextest
implicit none
complex*16 z
z=(-1.0d0,-0.0d0)
write(6,*) z
write(6,*) sqrt(z)
end program complextest
$ gfortran -Wall -ffree-form -o complextest complextest.f && ./complextest
  ( -1.0000000000000000     , -0.0000000000000000     )
  (  0.0000000000000000     , -1.0000000000000000     )
$

Fortranははじめから複素数が扱えるすばらしい言語です。

さて、Rubyでは

$ ruby -r complex -e 'z=Complex(-1.0,-0.0); p z; p Math::sqrt(z)'
(-1.0-0.0i)
(0.0-1.0i)

です。
(ここらへん訂正しました。ごめんなさい。)

Ruby 2.1からはiが使えるようになったのですが、

$ ./ruby --disable-gems -e 'p -1.0-0.0i'
(-1.0+0.0i)

と虚部の-0.0が+0.0になってしまいます。これは

$ ./ruby --disable-gems -e 'p Complex(-1.0,0.0)-Complex(0.0,-0.0)'
(-1.0+0.0i)

のように内部的に解釈されるのでしかたがないようです。たぶん。

ここらへんのことはRubyのメーリングリストに昔テキトーかつ無責任に書き散らしたのですが、
いつのまにかlib/complex.rbがcomplex.cになったり、
Flonumが導入されて実数浮動小数点数の計算が高速化されたり、
ホントにGMPが組み込まれたり、
とRubyでの数値計算環境がちゃくちゃくと整いつつあるのは驚くばかりです。
ありがたいです。

先日の日記でRubyの最新ソースをゴニョゴニョしていたのはこれらを見てみるためでした。
しかし、あまり手を広げられないので今回は泣く泣く撤退します。
どなたか複素数の数学関数をたくさん実装してください。

最後に、David Goldberg 著 西村恕彦 訳『浮動小数点演算について計算機科学者は何を知っておくべきか』の現在の書誌情報3つを次にリストしておきます。
sqrt[-x+i(+0)]=i*sqrt(x)
sqrt[-x+i(-0)]=-i*sqrt(x)
ってことにすると便利なのでそうなっている、ということが2.2.3節「符号つきゼロ」に書いてあります。
がんばれば一晩で読める分量なのでオススメです。「言語仕様は、理想的には
プログラムについての命題を証明するのに十分なだけの精密さで、言語の意味を定義
すべきである。これは言語仕様における整数の部分に対しては通常成立しているのに、
浮動小数点になると広い灰色領域がしばしば放置されている(modula-3は例外である)。」
と辛口だったり、謝辞に「午前8時の教室に間に合うように起きなくても、浮動小数
点と計算機システムの相互作用を学べることを、この論文のねらいとした。」などと
あったりしておもしろいです。IEEE標準についても詳しく書いてあります。

★原論文
@article{goldberg1991ecs,
    title={What every computer scientist should know about floating-point arithmetic},
    author={David Goldberg},
    journal={ACM Computing Surveys},
    volume={23},
    number={1},
    pages={5--48},
    year={1991}}
http://dl.acm.org/citation.cfm?id=103163

★西村恕彦 訳『浮動小数点演算について計算機科学者は何を知っておくべきか』
Bit(1993年9月号別冊臨時増刊)
コンピュータ・サイエンス '91
共立出版株式会社
pp.5--43
http://iss.ndl.go.jp/books/R100000039-I001404293-00
訳がすばらしいです。

★Sun訳『浮動小数点演算について』
http://docs.oracle.com/cd/E19957-01/806-4847/ncg_goldberg.html (テキストエンコーディングはEUC)

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by Anonymous Coward on 2014年04月07日 21時56分 (#2577289)

    gccもずいぶん昔から複素数型をサポートしてたりします。C++ではありません。C言語のgcc拡張です。

    http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Complex.html#Complex [gnu.org]

    むかーし、まだ前世紀だったかな、gccの複素数型でIEEE754と異なる挙動になるバグがあったので下手くそな英語でバグレポートしたような記憶が。

    • コメントありがとうございます。

      C99で複素数が扱えることやtgmath.hのことは知っているのですが、
      どのくらい昔から使えたかは知りませんでした。「tgmath history」
      でググると "The header tgmath.h first appeared in FreeBSD 5.3."
      って記述が見つかります。

      一方Fortranは http://ja.wikipedia.org/wiki/FORTRAN [wikipedia.org]
      によると1958年のFORTRAN IIに後からDOUBLE PRECISION
      (倍精度型)とCOMPLEX(複素数型)が追加されたみたいです。

      --
      love && peace && free_software
      t-nissie
      親コメント
typodupeerror

にわかな奴ほど語りたがる -- あるハッカー

読み込み中...