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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

5回答

4561閲覧

double型のメモリ領域

strike1217

総合スコア651

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2017/03/06 05:59

編集2017/03/06 06:13

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

C++

1#include<iostream> 2#include<math.h> 3 4int main(){ 5 double x = 1.7320508075688774152212090484681539237499237060546875; 6 int exp; 7 8 double k = frexp(x, &exp); 9 10 printf("%1.80lf = \n%1.80lf x 2 ^ %05d\n", x, k, exp); 11 return 0; 12}

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

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桁を超えるような値を直接入れている今回の状況は・・・オーバーフロー起きてしまっているんでしょうか?

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

現代の地球上では、数を表すのに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 07:22

編集2017/03/06 08:56
ikedas

総合スコア4335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2017/03/06 08:52

10進数の小数は2進数では"全て"循環小数になるのですか? 0.625 → 0.101となるようですが・・・
ikedas

2017/03/06 08:54

そうですね(^^;)。修正します。
strike1217

2017/03/06 11:40

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

2017/03/06 14:55

そうとも言えます。 たとえが適切かわかりませんが、大工道具の曲尺には普通の目盛りの他に「丸目」がありますよね。人間の10進法を変換するとき、コンピュータは2進法という別の「目盛り」を使っているので、正確な値を読み取れません。 また、物理や化学では、測器で読み取れる測定値には誤差があると考えて、「有効数字」に気をつけて計算しますよね。コンピュータの有効数字は52ビットなどと決まっているので、計算結果を10進法に変換しても、有効数字を超える桁の数字には意味がないのです。
strike1217

2017/04/05 05:07

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

0

こんにちは。

つまり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 07:22

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2017/03/06 09:03 編集

む・・・難しいです。 10進数に変換する際に出てた15桁を超えた桁も 2進数の時には53桁内に収まっていると考えて良いでしょうか? 2進数で仮数部53桁を超える桁をdouble型には入れられないですよね?
Chironian

2017/03/06 09:12

10進数を2進数へ変換する際に2進数53桁目までに収まらなかった場合、2進数54桁目まで計算し、その54桁目の値を四捨五入(零捨一入)します。 > 2進数で仮数部53桁を超える桁をdouble型には入れられないですよね? その通りです。
strike1217

2017/03/06 11:38

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

2017/03/06 15:17

その通りです!
guest

0

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

この余分な桁は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 09:29

編集2017/03/06 09:35
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2017/03/06 11:36

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

0

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

投稿2017/03/06 06:23

katsuya141

総合スコア367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2017/03/06 08:53

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

0

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

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

投稿2017/03/06 08:58

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問