Hatena::Diary

とある電気系出身者のいんでっくす

2010-04-23

浮動小数点を10進数行う基盤があればすべて終わりなんじゃないの?

そしたら全部ピュアな数学の世界になって, 計算機の誤差とかの人は全員失職するけど, 明らかにそうなったらいいよね. どうすればいいんだろう.

BigDecimalとか, 浮動小数点の誤差を中で整数で数値を保持することで吸入するソフトウェアレイヤーでのクラスはあるし, これはわりと思いつく. たぶん研究レベルではこの方針でより高速なものとかも開発されてると思う.

だけど, そもそもは, ハードウェアアーキテクチャが2進数ベースで演算を行ってるからいけないんじゃないか. たぶんだけど, 半導体トランジスタ)がONかOFFの二値しかとれないという事実に依存していてそれを上位で吸収する気がないからどんどん伝搬しているということで, 本当ならば人間が蓄えてきた数学という基盤に合うようなものを考案すべきなんだ.

というわけで, 半導体が10進数を表現出来ればいい. そのためには何が必要かというと, きっと量子レベルでの磁気による分岐とかかな. なんかあったよね. そういうレベルでの特性を使って, 10進数を表現出来るトランジスタを作って, それをベースに計算機アーキテクチャを作り直せば, スーパー上位でのプログラミングレイヤーで10進数演算における誤差とかを一切気にせず良くなる. もちろん無限桁にはならないだろうからそういう点での誤差は出るでしょうけど, 2進数は大雑把すぎる気がしてならない.

テスト書いてると, 誤差を考慮したテストを書く必要がある. 例えば, ある時は0が-0になってエクザクトな等値判定だと失敗するので, deltaを考慮したりということになるんだけど, めっさめんどくさい. これを全部なくせたら世の中もっとハッピーになるよね. 既存のCPUとか全部作り直しで半端じゃないコストかかるけど, 2進数ソフトウェアを10進数ハードウェアで動かすようなラッパーを作ればいいんだし, そしたらピュアに二進数ソフトウェアは低速で動作するハメになる(例えばシフトとかめっさ遅くなると思う)けど, そういうのはほっといて, なんか人類は計算機アーキテクチャを変えるべきなんじゃないかと思ってきた. 並列処理とか, そういうのにもデフォで対応した, 新しいアーキテクチャが必要な感じがする.

と, ソフトウェアレイヤーの人は思うんだ. もっと楽させてくれよ. ハードウェアやさんがんばれ!!まぁ現状としては, ソフトウェアレイヤーで吸収するのがいいのかなとは思う・・・. けどパフォーマンスの劣化がひどすぎる. さすがに許容出来ない. Rubyとかはデフォルトでそうなってたっけ?そんなわけはないか. でもあの言語はそういう用途で使うものだし(誰もあれで計算をしたくない), いいと思う.

shiroshiro 2010/04/24 08:41 浮動小数点数の計算誤差は、有効数字が有限桁であることに起因するので、2進数でも10進数でも手間は変わらないと思います。もし割り算を2と5の公倍数でしか行わない、というのであれば10進数が有利ですが。
10進数で書かれた小数を読み込んだり10進数で書き出したりするルーチンは10による割り算が発生するので、内部が2進数だと誤差が発生します。これは計算誤差の一種ではありますが、問題のごく一部にすぎません。

akiradeveloperakiradeveloper 2010/04/24 09:36 なるほど. 確かにそうかも知れませんね.

ではやはり, IEEEの新しい規格だと, 4倍精度の浮動小数点が定義されているようです. 実質的にこれを使うことで実数による演算と同等のことが出来ると思いますか?ハードウェアが128bit対応してないので遅そうですけど. でも結局, 等値判定で微小量を使うという発想は回避出来ないんでしょうね.

というわけで, 浮動小数によるこれらの問題は絶対に回避不能なのでしょうか?プリミティブの二項演算で誤差が出てる時点でもう絶望的です.

浮動小数点演算のテストは手間な上に, epsilonをいくつにするかとかそういった暗黙のセマンティクスに依存しすぎてテストに対して後方互換を保証することが大変になってきます. これが実数による演算ならめっちゃ楽なんですけどね・・・.

aa 2010/04/24 15:20 まさか本物のShiroさんがこんなところに…

773773 2010/04/24 19:44 そもそも無理数の正確な値を表現できる方法があるんでしょうか?
近似値を扱う以上誤差は避けられません。

http://en.wikipedia.org/wiki/IEEE_754-2008

akiradeveloperakiradeveloper 2010/04/24 20:53 > a
こんなところとはひどいですね

akiradeveloperakiradeveloper 2010/04/24 20:59 > 773
無理数を表現する方法はないので, 純粋な数学のレイヤーでその部分については死にます.

もし, doubleを使えば最悪ケースでも2桁は保証とかそういう特性があればいいのですが, あいにく情報落ちでビットが全死することがありますし, もはやビットを足して何かを表現するという演算機構自体が悪いのではと思えてきます.

773773 2010/04/24 22:31 誤差のない実数を表現することが困難であるという事情を考慮のうえで、実際問題として近似値を扱うのが浮動小数点方式だったり、計算誤差のノウハウだったりするわけですね。
πの値を正確に扱うことはできませんが、実用的でないわけではありません。

akiradeveloperakiradeveloper 2010/04/24 22:37 > 773
パイは一回, 200桁まで覚えたことがありますが, 実際に必要なのはやっぱり上3桁だけです. 次の数値は1なので元から比べるとほぼゴミです.
パイってどんな時に実用的なんですか?

aa 2010/04/25 00:59 なるほど、本スレの主張が有害だから社会的悪影響を防ぐためにShiroさんがコメントしたのですね。

akiradeveloperakiradeveloper 2010/04/25 07:28 > a
でしょうね.

shiroshiro 2010/04/25 11:11 あれれ、なんか紛糾しちゃったみたい…
10進数をハードサポートっていうのは突飛な考えではないでしょう。実際、x86だってbinary coded decimalという形で10進演算をサポートしてるわけですし (今や単に互換性のために残されてるだけで、使うメリットはほぼ無いですが)。四則演算に限るなら、有理数で計算すれば誤差は出ないので、有理数演算をネイティブでサポートするハードとかあると面白いかもしれません。
一般の実数を誤差無く扱うのは、コメントにもありますが具体的な数値計算をしようとすると不可能でしょう (数式処理で、無理数を無理数のまま扱うのなら可能でしょうが)。けれども、各計算について、それに伴う誤差の最大値というのは計算できるので、誤差範囲つきの数値の計算というのをハードとか言語の低レベルなところでサポートするというのはありだと思います (SICPにそういう計算の例が出てきたと思います)。
なので、「浮動小数点数計算の誤差うざい、ハードでサポートしてくれればいいのに」というアイディアは悪くないと思いますよ。それと基数の選択とはあんまり関係がないってだけで。

akiradeveloperakiradeveloper 2010/04/25 13:45 有理数演算はgcdのコストが高くなるので, 実装が重要と思いますが, 整数演算は高速なので, 有理数演算に最適化されたハードは面白そうですね.

でもまずは, 実験的に言語レイヤーで浮動小数点演算をすべて透過的に有理数で行うものを作る必要があると思いますね. オーバーフローとかどうやって対処するのか分かりませんけど. 最大公約数を高速に求めるハードウェアがあれば良い気がします.

いずれにしろ, 高速で安全なものを作るのであれば, ハードウェアのアーキテクチャから変えないと限界に来てる気がします. 今までもそうでしたが, CPUの高速化, メモリの大容量化によって, シミュレーションが活発になります. これは誤差が命取りになるドメインですし, 誤差をどうするかという研究は隣の建物でもされています. だけどもう, 鼻から誤差がありませんという方がコードもきれいになりますので, そうした方がいいのかなと思いました.

ハードウェアは言語より難解で, ソフトウェアにおける技術がほとんど利用不能です. 設計や開発のコストも高くx86を脱することはほとんど不可能ですが, ソフトウェアのレイヤーでアーキテクチャを表現して, その基盤で有理数による浮動小数点演算を実現することは可能です(めちゃくちゃ遅くなりそうですけど).

というわけでよろしくお願いします.

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/akiradeveloper/20100423/1271986775
おとなり日記