Go to the first, previous, next, last section, table of contents.


モード 練習問題 1 解答「3#0.1 = 3#0.0222222?」

Calc は数値を常に10進数で内部記憶しています。たとえ 1/3 が3進数で厳密に 表現された(`3#0.1')としても、計算ソフトのメモリ内部ではやっぱり 0.3333333 (普通12桁めで切捨てられますが、精度を上げても同じ事です)として 記憶されているのです。この不正確な数値を表示するため3進数に変換したら、 やはり不正確でしょう。この数値を3倍したら、やはり不正確な数値 0.999999 を得るのです。
(訳注: これを3進数で表現すると `3#0.222222...' となる。)

数値を3進数で表示するとき、Calc は何桁表示するか決めなければなりません。 現行精度が(10進で)12桁の場合、それは3進数で `12 / log10(3) = 25.15' 桁に対応します。25.15 は整数ではありませんから、Calc は25桁だけ表示しま す。すると、内部記憶された数値情報には、少しだけ画面表示されない部分があ ります。ジョーが `3#0.2' を入力したとき内部記憶された数値 0.666666 は、最後の0.15桁が失われた際に偶然心地良い値に丸められたのです。しかし Calc のメモリ内では依然として不正確なままです。そして彼が 2 で除算したと き、やはり恐れていた不正確な値 0.333333 を得たのです。 (実は、彼は 0.666667 を 2 で割って 0.333334 を得ました。 これが 3#0.1 より少し大きい答を得た理由です。)

こんなことに悩まされたくなかったら、ジョーは M-24 d n とタイプして、 デフォルトより1桁少なく表示すれば良かったのです。(もしマイナスの引数で d n としたら、「デフォルト桁数_マイナス_引数」の桁数で表示します。 だから M-- d n は同じ効果を得るための、より簡単な方法です。) 誤差 は依然としてそこに潜んでいるのですが、今やそれは表示目的に見栄え良く丸め られます。(3進数の `0.022222' は10進数の `0.099999' みたいなも のだということを思い起こして下さい。1桁丸めれば、全体が `0.1' にな るのです。) あなたの計算の性質次第ですが、この誤差隠しは役に立つこともあ り、また危険でもあります。d n コマンドによって、Calc はあなたに選 択権を(訳注: つまりは結果責任を)与えているのです。

ついでに別の作用にも触れておきますが、M-30 d n とタイプして表示桁 数を「実質」よりも増やしたら、表示された数値の末尾に無意味なゴミの桁を見 ることになります。(10 進形式で内部記憶された数値を10進形式で表示する場合 は、無意味桁は常にゼロです。だからそれらは消滅してしまい、気付くことはあ りません。) Calc は例の0.15桁を丸めるので、2つの数値が内部で少し違うにも かかわらず、同じに見えてしまう危険性があります。もしそれが気になる場合は、 d n の精度を普通より少し高めに設定しておくことをおすすめします。不 細工なゴミを見ることになりますが、常に2つの異なる数を見分けることができ ます。

ちょっとこぼれ話を。大概のコンピューターは浮動小数点値をバイナリで内部記 憶し、10進数に変換して表示しています。そのようなプログラムは常に同じ問題 にぶつかります。10進の0.1をバイナリでは厳密に表現できない(0.1 d 2 を試してみなさい)のです。(上でやったように、1桁丸めて誤差を隠すのが一般 的ですが)いくつかのマシンでは `0.1 * 10' の結果が厳密に1にはなりま せん。Calc はバイナリではなく10進で動いているので、10進表示モードである限り 「厳密に見える数は厳密である」ことが確実です。

2進, 8進, 16進で厳密に表現できる数が、10進でも厳密であることを示すことは 難しくありません。この練習問題で見たような種類の問題は、比較的普通でない 3のような基数を使うときしか深刻にならないでしょう。


Go to the first, previous, next, last section, table of contents.     利用度数