検索条件
全2件
(1/1ページ)
123456789123456 - 123456789121111 = 2345非常に近い2つの数同士の引き算を行なうと、「桁落ち」と呼ばれる有効数字の減少が発生します。これは有限精度の計算を行っている以上仕方のないことですが、どうやらこの関数電卓では、
123456789123456 - 123456789123111 = 345
123456789123456 - 123456789123411 = 0 (45でない!)
「減算で桁落ちが発生した結果有効数字が2桁以下になったとき、その数を強制的に0に書き換える」という仕様になっているようです。桁落ちが起きるような厳しい計算こそ高精度な電卓の助けが欲しいところなのに、そこでわざわざかろうじて残った情報を捨て去ってしまうというのは極めて不可解な仕様だと感じます。
0.9999996 x2 - 2x + 1.0000004 = 0の解をいわゆる2次方程式の解の公式で計算してみます。判別式の値は、
4 - 4 × 0.9999996 × 1.0000004ですが、この値が
= 4 - 3.99999999999936
= 0.00000000000064
= 6.4 × 10-13
4 - 3.99999999999936 = 0となってしまいます。3.99999999999936を正しく格納できる仮数部を持っているにも関わらず、です。実にもったいない仕様だとは思いませんか。素直な10進数15桁の演算ならば、
sqrt(6.4 × 10-13) = 8 × 10-7のようにほぼ正確に計算できたはずなのに、
x1 = (2 - 8×10-7)/2/0.9999996 = 1
x2 = (2 + 8×10-7)/2/0.9999996 ≈ 1.000000800000032
x1 ≈ 1.00000040000016のような重解になってしまいます。また、手作業で解の公式を使って計算した場合のみならず、関数電卓に組み込まれた2次方程式ソルバーを使っても全く同じ計算結果が得られました。すなわち、ユーザに直接見える部分のみならず、内部の演算ルーチンそのものがこの仕様に蝕まれていることは確実と思われます。
x2 ≈ 1.00000040000016
機種名 | 仮数部の桁数 | 桁落ち時に捨てられる桁数 |
---|---|---|
カシオ fx-5800P/JP900/FD10Pro/375ES/72F | 15 | 2 |
キヤノン F-789SG | 18 | 2 |
キヤノン F-715SA | 16 | 3 |
シャープ EL-509M | 14 | 1 |
sudo apt install emscriptenで入れてもうまく動かない模様です。clang/llvmのバージョンの問題っぽいがよく分かりません。
sudo apt install cmakePortable Emscripten SDK for Linux and OS X (emsdk-portable.tar.gz) をダウンロードして展開し、その中にcdして
./emsdk update ./emsdk install latest ./emsdk activate latestします。最後の作業で/home/kashi/.emscriptenが作られました。これでインストールは終了。使う前に
source emsdk_env.shでPATHの設定が必要です。
emcc test.cc node a.out.jsで動くのを確認しました。
ln -s /usr/include/boost ホームのどこかとリンクを張ってしまって、-Iにそれを指定してごまかしました。これが正しいかどうかは分かりません。また、javascriptの中ではfesetroundによる丸めの向きの変更は効かないので、そのままでは精度保証出来ません。kvは-DKV_NOHWROUNDを付けると丸めの向きの変更を行わずエミュレーションで方向付き丸めを行なう機能を持っており、それをつけるとちゃんと精度保証付きで計算してくれるようです。
emcc -I(kvの場所) -I(boostの場所) -DKV_NOHWROUND hoge.ccみたいな感じです。kvのサンプルはmpfrを使ったもの以外は大体動きそうです。実行速度はちゃんと測ってませんがネイティブのC++の30倍程度でしょうか。htmlに変換してfirefoxに食わせた方がnode.jsより速いようにも見えました。