- ベストアンサー
有効桁数の数え方・誤差
actionscriptをやっているのですが、有効桁数の数え方がよくわかりません。 たとえばNumber(有効桁数15桁)で public function sample() { var tf : TextField = new TextField(); var suuji : Number = 0.999; var suuji2 : Number = 1.001; var kekka : Number; kekka = suuji2 - suuji; tf.text = "" suuji2 + "-" suuji + "=" + kekka; } というものを実行させた場合kekkaが0.0019999999999998908になるのですが、この際の各々の変数の有効桁数は suuji 3桁 suuji2 4桁 kekka 0桁 という解釈で良いのでしょうか? そしてこの場合は桁落ちが起きていると言えるのでしょうか? また、この際にkekkaに誤差がでるのはNumberの有効桁数が15桁であるため、それ以降の桁に勝手に数字が入れられるということでしょうか? (0.999が勝手に0.9990000000000001092になる) もうひとつわからないことがあって、これは型の有効桁数を調べるプログラムなんですけど、 public function sample2() { var n : int; var sb : Number,sn : Number,t : Number; var tf : TextField = new TextField(); tf.border = true; tf.width = 400; tf.height = 300; n = 1; sn = t = 1.0; sb =0.0; while(sn != sb){ tf.appendText(n + ":" + sn + ":" + t + "\n"); n++; t = t / 10.0; sb = sn; sn = sb + t; } addChild(tf); } を実行すると 1:1:1 2:1.1:0.1 3:1.11:0.01 4:1.111:0.001 5:1.1111:0.0001 6:1.11111:0.00001 7:1.111111:0.0000010000000000000002 8:1.1111111:1.0000000000000002e-7 9:1.11111111:1.0000000000000002e-8 10:1.111111111:1.0000000000000003e-9 11:1.1111111111:1.0000000000000003e-10 12:1.11111111111:1.0000000000000003e-11 13:1.1111111111110001:1.0000000000000002e-12 14:1.1111111111111:1.0000000000000002e-13 15:1.11111111111111:1.0000000000000002e-14 16:1.1111111111111112:1e-15 と表示されるのですが、これだと16行目の有効桁数が16桁になっているのでしょうか? しかしそれだと型の有効桁数と矛盾するので、たまたま16桁目が1だっただけで有効桁数は15ということでしょうか? また、tに2や3の数字が勝手に入れらていますが、これも上記のように有効桁数ではない部分に勝手に数字を入れられているということでしょうか? 長文、また見辛く申し訳ありません。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>var suuji : Number = 0.999; >var suuji2 : Number = 1.001; >というものを実行させた場合kekkaが0.0019999999999998908になるのですが、この >際の各々の変数の有効桁数は >suuji 3桁 >suuji2 4桁 >kekka 0桁 >という解釈で良いのでしょうか? Number型であれば有効桁数は変わりません。 ただし数学的な有効桁数の定義としてsuuji,suuji2が3桁,4桁というのはあっている気はします。 次のように各変数の値は格納されています。(10進数表記と16進数表記) suuji = 0.99900000000000000(3feff7ce d916872b) suuji2= 1.0009999999999999(3ff00418 9374bc6a) kekka = 0.0019999999999998908(3f60624d d2f1a900) 理想 = 0.0020000000000000000(3f60624d d2f1a9fc) 見てわかるとおりsuuji2は既に1.001ではありません。 suuji2を丸め誤差を考え表示した場合は1.001となります。 2進数を使った浮動小数点ではで表せない10進数の小数がある為,浮動小数を表示する場合は表示桁数を参考に丸め誤差を補正しています。 kekkaも同じく丸めによる値を補正すれば0.002と表示されるはずです。 >そしてこの場合は桁落ちが起きていると言えるのでしょうか? この2つの値はほぼ同じ値での引き算なので,桁落ちは発生しています。 >また、この際にkekkaに誤差がでるのはNumberの有効桁数が15桁であるため、それ以降の桁に勝手に数字が入れられるということでしょうか? 浮動小数点は2進数で計算を行っている為,少しだけ違います。実際に計算結果を記述しましたので桁落ちした点を見てイメージしてください。 suuji = 0x3feff7ce d916872b 0011 1111 1110 1111 1111 0111 1100 1110 1101 1001 0001 0110 1000 0111 0010 1011 011 1111 1110 = 1022 - 1023 = -1なので2^-1 1.1111 1111 0111 1100 1110 1101 1001 0001 0110 1000 0111 0010 1011 0.1 1111 1111 0111 1100 1110 1101 1001 0001 0110 1000 0111 0010 1011 =0.11111111101111100111011011001000101101000011100101011 ←2進数での小数表現 suuji2 = 0x3ff00418 9374bc6a 0011 1111 1111 0000 0000 0100 0001 1000 1001 0011 0111 0100 1011 1100 0110 1010 011 1111 1111 = 1023 - 1023 = 0なので2^0 1.0000 0000 0100 0001 1000 1001 0011 0111 0100 1011 1100 0110 1010 1.0000 0000 0100 0001 1000 1001 0011 0111 0100 1011 1100 0110 1010 =1.0000000001000001100010010011011101001011110001101010 ←2進数での小数表現 kekka = 0x3f60624d d2f1a900 0 01111110110 00000110001001001101110100101111000110101001 00000000 suuji2 - suujiの計算は次のようになります。(単純に2進数の引き算) 1.0000000001000001100010010011011101001011110001101010 -0.11111111101111100111011011001000101101000011100101011 --------------------------------------------------------- 0.00000000100000110001001001101110100101111000110101001 正規化して浮動小数点表記 1.00000110001001001101110100101111000110101001 * 2 ^-9 -9 + 1023 = 1014 0 01111110110 00000110001001001101110100101111000110101001 ******** 桁落ち6ビット この計算結果とkekkaは同じになります。 >(0.999が勝手に0.9990000000000001092になる) これは0.999が浮動小数点で表せない為です。有効桁数を超える部分は表示されても意味を持たないと考えるべきです。
その他の回答 (3)
- goosyu
- ベストアンサー率58% (36/62)
まず64ビットの浮動小数点(倍精度 IEEE-754)では有効桁数が15桁~16桁(または約15桁)です。 ただしNumber型の有効桁数が15桁と記述されているであれば,値によって有効桁数が変わるというのは扱いづらいので15桁ということで整理されたと考えられます。 この為,[1.111111111111111]2は有効桁数16桁,[9.99999999999999]8は有効桁数15桁ということで問題はないと考えます。 つまりNumber型がどんな値でも保証出来る有効桁数は15桁まで。ただし値によっては16桁まで対応出来る場合があります。 ちなみに整数の有効桁数は2^53-1=9007199254740991,約15.9桁ですので同じく有効桁数15桁~16桁となります。 (この検証として9007199254740993は表せないことになります。)
お礼
分かりやすい回答ありがとうございます! 大変助かりました!
- goosyu
- ベストアンサー率58% (36/62)
>ですが、この場合桁落ち6ビットではなく8ビットですよね? →寝ぼけていました。8ビットですね。 >と表示されるのですが、これだと16行目の有効桁数が16桁になっているのでしょうか? >しかしそれだと型の有効桁数と矛盾するので、たまたま16桁目が1だっただけで有効桁数は15ということでしょうか? →出来るだけ反映されていると思います。また有効桁数が16桁とすると例えば9.999999999999999が正しく表現される必要があります。(すいません未確認ですが。)
補足
9.999999999999999が9.999999999999998になりましたので有効桁数は16桁ではないみたいです。 Numberが表現できる値でもっとも近い数字が1.1111111111111112であり、有効桁数は15桁([1.11111111111111]12 []内が有効)という理解でよいでしょうか?
- salsberry
- ベストアンサー率69% (495/711)
> この際にkekkaに誤差がでるのはNumberの有効桁数が15桁であるため、それ以降の桁に勝手に数字が入れられるということでしょうか? > (0.999が勝手に0.9990000000000001092になる) > tに2や3の数字が勝手に入れらていますが、これも上記のように有効桁数ではない部分に勝手に数字を入れられているということでしょうか? 決して「勝手に入れられている」わけではありません。 たとえば10進数の0.1を2進数で表すと循環小数になってしまうので、有限桁数の2進数では10進数の0.1を正確に表すことは根本的にできないのです。 上記の出力で1.0/10.0の結果が端数なしにきちんと「0.1」と表示されているじゃないかと思われるかもしれませんが、実際には「0.1にできるだけ近い値」であって、正確な0.1ではありません。0.000001のあたりまで行くとそのわずかな誤差が表示にも出てきてしまっているだけです。
お礼
浮動小数点数の場合は表すことができない数字があるのですね。 回答ありがとうございました!
お礼
丁寧な回答ありがとうございます! 浮動小数点数の仕組みの理解ができました。 ですが、この場合桁落ち6ビットではなく8ビットですよね? また、 >(0.999が勝手に0.9990000000000001092になる) と書きましたがそうではなく、suuji2の方が浮動小数点数では表せない数字だったため計算結果がおかしくなったのですね。 本当にありがとうございました!