アフィリエイト広告を利用しています

広告

posted by fanblog

2018年03月27日

《その350》double型の内部表現(2)


 double型の内部表現

 double型の内部表現を記述する際の考え方を使って、前回《349》、プログラムを使わずに、実際の数値の内部表現を求めました。

 下記のプログラムは、前回のときの考え方をそのまま使って作成したもので、あまりキレイなコードではありませんが、一応の確認には使えるため、今回はこれを利用して、いくつかの数値の内部表現を見てみました。

 前回と同じ値 0.6, −12.75 も試してみました。
また、2.0, 0.0625 なども試しましたが、これらの数値には 1 のビットが一つしかないので出力結果が 0 だらけになってしまって、一瞬、焦ります。落ち着いて考えれば納得できますが・・・。

 最後の numeric_limits<double> は、付け足しです。


#include <string>
#include <limits>
#include <iostream>
using namespace std;

string to_str(double x);

void print(string x) {
int n = 0;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++)
cout << x[n++];
cout << ' ';
}
cout << '\n';
}

int main() {
cout << "◆double型数値の内部表現\n";
double d;
d = 0.6; cout << "◇" << d << '\n';
print(to_str(0.6));
d = -12.75; cout << "◇" << d << '\n';
print(to_str(-12.75));
d = 2.0; cout << "◇" << d << '\n';
print(to_str(2.0));
d = 0.0625; cout << "◇" << d << '\n';
print(to_str(0.0625));
d = -0.00012; cout << "◇" << d << '\n';
print(to_str(-0.00012));

cout << "\n\nnumeric_limits<double>\n";
cout << "最小値 : "
<< numeric_limits<double>::min()
<< '\n';
cout << "最大値 : "
<< numeric_limits<double>::max()
<< '\n';
cout << "桁数(2進) : "
<< numeric_limits<double>::digits
<< '\n';
cout << "桁数(10進) : "
<< numeric_limits<double>::digits10
<< '\n';
cout << "指数下限 : "
<< numeric_limits<double>::min_exponent
<< '\n';
cout << "指数下限(10進) : "
<< numeric_limits<double>::min_exponent10
<< '\n';
cout << "指数上限 : "
<< numeric_limits<double>::max_exponent
<< '\n';
cout << "指数上限(10進) : "
<< numeric_limits<double>::max_exponent10
<< '\n';
cout << "基数 : "
<< numeric_limits<double>::radix
<< '\n';
cout << "機械ε : "
<< numeric_limits<double>::epsilon()
<< '\n';
cout << "機械ε(\"1より大きい表現可能な最小数\""
"と\"1\"との差)\n";
}


string to_bits(int x) {
string str = "";
while (x) {
if (x % 2) str = '1' + str;
else str = '0' + str;
x /= 2;
}
return str;
}


string to_str(double x) {
// 左端の符号ビット
string sign = (x > 0) ? "0" : "1";
double tmp = (x > 0) ? x : -x;

int a = (int)tmp; // 整数部分(10進数)
double b = tmp - a; // 小数部分(10進数)

// 整数部分の2進数表現文字列
string str1 = to_bits(a);

int exp = 0; // 指数
if (str1 != "") {
exp = str1.size() - 1;
str1.erase(0, 1); // 先頭の 1 を削除
}

string str2 = ""; // 小数部分
int limit = 53 - exp; // 最大で 53桁必要
int f = 0; // フラグ
while (b) {
if (b * 2 >= 1) {
str2 = str2 + '1';
b = b - 0.5;

// 最初の 1 が出現したら f = 1
f = 1;
}
else str2 = str2 + '0';
b *= 2;

// str2 は最初の 1 の桁以下 limit桁の長さ
if (f) --limit;
if (!limit) break;
}

int exp2;
if (str2 != "") {
exp2 = str2.find('1');

// 整数部分がなければ
if (str1 == "") {
// str2 の先頭の 1 を削除
str2.erase(0, exp2 + 1);
// 指数の算出
exp = -exp2 - 1;
}
}
// 指数を変換
exp = exp + 1023;

// 指数部分の2進数表現文字列
string str3 = to_bits(exp);

// 指数部は 11桁
str3 = string(11 - str3.size(), '0') + str3;

// 仮数部は 52桁
str1 += str2;
str1 = str1 + string(52 - str1.size(), '0');

// 全体で 64桁
return sign + str3 + str1;
}

h12_0031.png




この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/7482699
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。