
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の数字が勝手に入れらていますが、これも上記のように有効桁数ではない部分に勝手に数字を入れられているということでしょうか?
長文、また見辛く申し訳ありません。
No.2ベストアンサー
- 回答日時:
>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が浮動小数点で表せない為です。有効桁数を超える部分は表示されても意味を持たないと考えるべきです。
丁寧な回答ありがとうございます!
浮動小数点数の仕組みの理解ができました。
ですが、この場合桁落ち6ビットではなく8ビットですよね?
また、
>(0.999が勝手に0.9990000000000001092になる)
と書きましたがそうではなく、suuji2の方が浮動小数点数では表せない数字だったため計算結果がおかしくなったのですね。
本当にありがとうございました!
No.4
- 回答日時:
まず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は表せないことになります。)
No.3
- 回答日時:
>ですが、この場合桁落ち6ビットではなく8ビットですよね?
→寝ぼけていました。8ビットですね。
>と表示されるのですが、これだと16行目の有効桁数が16桁になっているのでしょうか?
>しかしそれだと型の有効桁数と矛盾するので、たまたま16桁目が1だっただけで有効桁数は15ということでしょうか?
→出来るだけ反映されていると思います。また有効桁数が16桁とすると例えば9.999999999999999が正しく表現される必要があります。(すいません未確認ですが。)
この回答への補足
9.999999999999999が9.999999999999998になりましたので有効桁数は16桁ではないみたいです。
Numberが表現できる値でもっとも近い数字が1.1111111111111112であり、有効桁数は15桁([1.11111111111111]12 []内が有効)という理解でよいでしょうか?
No.1
- 回答日時:
> この際に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のあたりまで行くとそのわずかな誤差が表示にも出てきてしまっているだけです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB6.0での小数点の扱いについて
-
c languageで 簡単な質問があ...
-
浮動小数演算は実行環境の変化...
-
Log関数に関する質問
-
PICで小数点の演算
-
計算の丸め誤差の解消について
-
Double型について
-
ExcelのINT関数の計算結果がお...
-
最早開始時間と最遅完了時刻を...
-
【C++】関数ポインタの使い方
-
既定のコンストラクタがありま...
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
-
信頼区間の1.96や1.65ってどこ...
-
a^2の√=a が成り立たない場合
-
配列をnビットシフトする
-
数学 一次関数 関数 y=-3/4x+k(...
-
C言語 エラーの原因がわからな...
-
#define _CRT_SECURE_NO_WARNIN...
-
プログラムでの数字につく”f”の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
有効数字について 以前質問をし...
-
c languageで 簡単な質問があ...
-
EXCELの関数"STDEV(標準偏差)"...
-
ExcelでPC(パソコン)によって...
-
三菱シーケンサ(Aシリーズ)で...
-
floatの有効桁数
-
255の2の補数、B'00000001'が-...
-
O(n log n)について2
-
符号誤り率の計算は例題でどの...
-
CRCの計算方法について
-
VB.net Double と...
-
コンピューターは指数関数をど...
-
16進数 加算 減算 C言語
-
ExcelのINT関数の計算結果がお...
-
C言語でセルオートマトンを作成...
-
BCD・HEX・BINについて
-
”/”を使わずに割り算したいんで...
-
三角比の俯角の計算
-
除算を使わずに10で割りたい。
-
VBAでミリ秒まで出力する方法
おすすめ情報