質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.96%

double型のメモリ領域

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 3,361

score 585

double型について教えてください。
前回の質問で、仮数部の箇所で確認があります。
実験コードを作っていみました。
mac os 64bitです。

#include<iostream>
#include<math.h>

int main(){
    double x = 1.7320508075688774152212090484681539237499237060546875;
    int exp;

    double k = frexp(x, &exp);

    printf("%1.80lf = \n%1.80lf x 2 ^ %05d\n", x, k, exp);
    return 0;
}


結果は以下のようになりました。

1.73205080756887741522120904846815392374992370605468750000000000000000000000000000 = 
0.86602540378443870761060452423407696187496185302734375000000000000000000000000000 x 2 ^ 00001

仮数部が15桁(53桁)であれば、上記のような結果がそのまま格納されていれば、オーバーフローになっているような気がします。
上記のような仮数部が全てdouble型の中に入っているわけではないですよね??

小数点以下の数値の場合、2で割り切れないので無駄に桁が増えます。
1ビットで1/2を表現できますね。0.5です。
2ビットなら1/4で0.25です。
3ビットなら1/8で0.125、4ビットなら1/16で0.0625ですね。
4ビットは10進数1桁ちょっとです。

コンピュータはどうやって2進数から10進数に変換しているのですか?
ここによりますと、

PCに使われているCPUは、直接10進数を扱うことは出来ません。
外部に出力するとき、サブルーチンで10進数に変換するのです

との事ですが、つまり2進数では53桁までがdouble型に格納されていて、10進数に変換される時(外部に出力される時)に余分な桁が付いてくるという理解で正しいでしょうか??
この余分な桁はdouble型の中には入っていないということですよね?
つまり、余分な桁数はdouble型に相当するメモリ領域の中には、存在しないということでよろしいでしょうか?

私の理解が間違っていたらご指摘をお願いします。

[追記]

前回の質問と状況が少し違うような気がしてきました。

漸化式でdouble型の中に値を格納している場合は10進数に変換される時に余分な桁が付いてくるものだと考えていますが、今回の質問では「double型の中に直接値を代入している」という点で違いが出てきています。

仮数部が15桁を超えるような値を直接入れている今回の状況は・・・オーバーフロー起きてしまっているんでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+4

現代の地球上では、数を表すのに10進記法を使う人が多いですが、何進法で表しても数は数です。

たとえば、10進法の0.5は、2進法では0.1と表せます。逆に言うと、2進法での0.1は、10進法では0.5と表せます。同様に考えると、

2進法 10進法
0.1 0.5
0.01 0.25
0.001 0.125
0.0001 0.0625
0.00001 0.03125
 ...         ... 
0.1^52   0.00000 00000 00000 22204 46049 25031 30808 47263 33618 16406 25 

となります。

仮数部が2進法で1.…(0が51個)…1、指数部が0の数があるとします。上の表によると、この数を10進法で正確に表すには、小数点以下52桁までもが必要です。とはいえ、多くの桁が必要になるのを気にしなければ、2進法から10進法への変換は正確にできます

では今度は、10進法から2進法への変換はどうなるでしょうか。10進数の0.10.01、…を2進法で表してみます (計算は自分でやってみて下さい。普通の割り算を2進法でやればいいのです、1からはじめて、1010で割ることを繰り返します)。

10進法 2進法
0.1 0.0 0011 0011…
 …   … 

いきなり最初で挫折しました。10進法で有限桁の小数で表せる数は、2進法では多くの場合に循環小数になり、有限の桁数では表せません。つまり、10進法からコンピュータの2進法への変換には、誤差が生じます

コンピュータで計算する場合、最初に人間が与える数値は10進法で表されていることが多いでしょう。この数値をコンピュータの内部で2進法で表すときに、すでに誤差が生じてしまいます。ですから、コンピュータの計算結果を10進法で表すときに、何十桁もの数で表しても正確にはなりません。

以上のようなわけで、コンピュータが扱える精度未満の桁に意味はありません。仮数部の52(+1)ビットで表すことのできる、10進法での16桁弱が、意味のある桁数ということになります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/06 20:40

    誤差があるから、10進数に変換された時に余分な桁がダラダラと現れてくるのですね。

    キャンセル

  • 2017/03/06 23:55

    そうとも言えます。

    たとえが適切かわかりませんが、大工道具の曲尺には普通の目盛りの他に「丸目」がありますよね。人間の10進法を変換するとき、コンピュータは2進法という別の「目盛り」を使っているので、正確な値を読み取れません。

    また、物理や化学では、測器で読み取れる測定値には誤差があると考えて、「有効数字」に気をつけて計算しますよね。コンピュータの有効数字は52ビットなどと決まっているので、計算結果を10進法に変換しても、有効数字を超える桁の数字には意味がないのです。

    キャンセル

  • 2017/04/05 14:07

    解決しました。
    ベストアンサーに迷いましたが、一番評価が高かったので!

    キャンセル

+3

こんにちは。

つまり2進数では53桁までがdouble型に格納されていて、10進数に変換される時(外部に出力される時)に余分な桁が付いてくるという理解で正しいでしょうか?? 

そのように解釈しても間違いではないと思いますが、正確でもありません。

この余分な桁はdouble型の中には入っていないということですよね?

いえ、違います。

例えば、2進数で0.0000から0.1111までに存在する2進数の数値の数は全部で16個ですね。(値が変化するのは4ビットですから。)
2進数の0.0000は10進数でも0です。
2進数の0.1111は10進数では1.0弱です。(2進数の0.0001を加えたら1.0ですから)
つまり、0.0~1.0の間を16等分してそれぞれに値を割り当てたものとなります。

この小数点下4桁の2進数で表現できる10進数の精度は何桁でしょうか?
10進数では0~1.0弱を10個の数値で表現し、それを1桁と呼びます。
ならば、0~1.0弱を16個の数値で表現した場合は、えいやっと1.6桁でも良いのでは?
これは4桁には全く届きません。でも、10進数で表現すると小数点下4桁になります。
10進数で小数点下4桁の場合、数値と数値の間は10進数で0.0001離れています。
2進数で小数点下4桁の場合、数値と数値の間は2進数で0.0001離れています。
2進数の0.0001は10進数で0.0625です。0.0001に比べると遥かに大きいです。まばらなのです。

分かりにくいですね。うまく伝えられなかったら、ごめんなさい。
なかなか説明が難しいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/06 17:59 編集

    む・・・難しいです。

    10進数に変換する際に出てた15桁を超えた桁も 2進数の時には53桁内に収まっていると考えて良いでしょうか?

    2進数で仮数部53桁を超える桁をdouble型には入れられないですよね?

    キャンセル

  • 2017/03/06 18:12

    10進数を2進数へ変換する際に2進数53桁目までに収まらなかった場合、2進数54桁目まで計算し、その54桁目の値を四捨五入(零捨一入)します。

    > 2進数で仮数部53桁を超える桁をdouble型には入れられないですよね?

    その通りです。

    キャンセル

  • 2017/03/06 20:38

    ようやく分かってきました。
    10進数では余分で不要な桁に見えても、2進数ではちゃんとdouble型の中に53桁以内で収まっているのですね!!

    キャンセル

  • 2017/03/07 00:17

    その通りです!

    キャンセル

+2

他の方の解説で充分なのですが・・・

この余分な桁はdouble型の中には入っていないということですよね?

あえていえば、入っているといった方がいいのかも知れませんね。

つまり、余分な桁数はdouble型に相当するメモリ領域の中には、存在しないということでよろしいでしょうか?

katsuya141さんがおっしゃるように「余分な桁数」という理解が多分間違っています。

計算機の内部でのIEE754の数値とそれを「正確に10進数で表現した数値表現」を列挙してみましょう。(idedasさんがおっしゃるように2進数表現の浮動小数点数は10進数表現へ無限小数を用いずに正確に変換できる点に注意してください)
質問者さんが例に挙げた数値は下の(2)ですがIEE754の内部表現の仮数部の最後の桁4bitは16進数表現でb(=1011)ですね。ではこの値の次に大きな値はなにかというと最後の桁をb->cにしたもの(3)です。同様にこの値より次に小さな値はb->aにしたもの(1)です。

    IEE754            10進数表現(厳密な値)
(1) 3ffbb67ae8584caa  1.732050807568877193176604123436845839023590087890625
                                       ^この桁が違ってます
(2) 3ffbb67ae8584cab  1.7320508075688774152212090484681539237499237060546875
(3) 3ffbb67ae8584cac  1.73205080756887763726581397349946200847625732421875
                                       ^この桁が違ってます


上の3つの浮動小数点数はそれぞれ正確に「10進数表現」の欄に記した値を保持しています。
それを10進数で正確に表現すれば確かに53ケタほどの値ですが、(1)(2)(3)はIEE754で表現可能な最小の差をもった値でありそれより小さな差の値は表現できません。「浮動小数点数は実数の中のとびとびの値(=離散値)しか表現できない」という事実はご存知ですね?
さて最初の値(2)とその前後の値(1)(3)をみると(2)の値は(1)よりは大きく(3)よりは小さい無数にある実数の中のどれか特定の値を誤差付きで表現した計算結果と捉えるべきですので、(2)の値を考えたとき、上に挙げた10進53ケタの値が正確な値だからといってその53ケタ全てを(2)の値の表現として考えてみても意味がなく、せいぜい「1.732050807568877くらいの値」と言うべきです。以上が倍精度浮動小数点数の10進での有効精度はせいぜい15桁程度であることの実例です。

以上の説明は他の方々の説明を単なる実例で示したものに過ぎません。他の方の回答で「なるほど」と理解できたならあまり役に立たない回答かと思いますが、一つの説明ではあるかなと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/06 20:36

    ふむふむ・・・

    みなさんの回答でだんだんわかってきたのですが、
    10進数で15桁を超えていても、double型の中に入っている2進数では53桁の中にちゃんと収まっているということですね!

    キャンセル

+1

「余分な桁が付いてくる」という表現がひっかかります
例えば3進数の0.1(3倍すると1になる数=3のマイナス1乗)は10進数にすると0.33333333333333...ですが、この3333..と長くなる部分を余分なものと呼ぶのか、サンブンノイチを正確に表現しようとして必要なものなので余分な桁ではないと言うかということだと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/06 17:53

    あ〜
    確かに余分ではなく必要な桁ですね。

    キャンセル

0

特殊な場合を除いて浮動小数点はIEEEの浮動小数点で表現されています。
下記に詳しく解説されています。

IEEE 浮動小数点表現
IEEE 754(IEEE 浮動小数点数演算標準)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.96%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る