
Cのdoubleの8バイトの浮動小数点がメモリ上でどの様に配置されているかを見たいので、以下のようなプログラムを作ってみてみました。結果、
d=2.0の時、
0 0 0 0 0 0 0 40
d=4.0の時、
0 0 0 0 0 0 10 40
d=8.0の時、
0 0 0 0 0 0 20 40
となる様なのですが、何故仮数部の表示がこの様な値になるのかが分かりかねています。環境は、
iMacのXcodeのCを使っています。
どなたか分かる方、ご教示ください。
#include <stdio.h>
int main(int argc, const char * argv[]) {
// insert code here...
double d = 2.0;
printf("%p\n", &d);
printf("%p\n", &d+1);
void *vp = &d;
char *cp = vp;
for (int i=0; i<8; i++) {
printf("%x ", *cp);
cp++;
}
printf("\n");
printf("%lf\n", d);
return 0;
}
No.1ベストアンサー
- 回答日時:
まずは、この資料を見て
・2.0,4.0,8.0を「正規化」してみる
・「正規化」した値を「64ビット倍精度の交換形式」に当てはめてビット列にしてみる
というのを自分の手でやってみてはいかがでしょうか?
16,32,64等の1バイト(8ビット)を複数組み合わせるデータの場合、どの順番にバイトが並んでいるかは環境によって違います。
大きく「リトルエンディアン」と「ビッグエンディアン」の2つがあります。
https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3 …
あなたの使っているiMacでCのdoubleを使った場合、「リトルエンディアン」が使われています。
> d=2.0の時、
> 0 0 0 0 0 0 0 40
これは、64ビットにすると
0x4000000000000000
になります。
同様に
4.0: 0x4010000000000000
8.0: 0x4020000000000000
> 何故仮数部の表示がこの様な値になるのか
0x40を仮数部の値だと思っての発言だと思われます。
実際は指数部(や符号)の値です
No.3
- 回答日時:
ねんのためだけど勘違いするといけないのでちょっとコメント.
まず, どんな型であっても「値をどのように表現/格納するのか」は C の規格では規定されていない. もちろん一定の制限はあるけど, その制限さえ満たせていればどのように表現しようと (C の規格上は) 問題ない. つまり, ここでの結果はあくまで「あなたの使ったシステムではそうなる」というだけであって, 「C という言語においてそのようになっている」ということではない. まあ, そもそも「double が 8バイト」という決まりがあるわけでもないし.
とはいえ「一般的に用いられる方法」というのはやはりあって, PC なんかだと IEEE754 (IEC 60559) という形式が de facto standard になっている.
あと, 例えば double が 8バイトであるとしてもそのバイトがどのように並んでいるのかは (C では) 規定されていない. big endian と little endian がふつうだけど, 歴史的にはそうでないものもあった.
あとプログラムについて突っ込んでおくと, 少なくとも
char *cp = vp;
は
unsigned char *cp = vp;
とすることが望ましい. そのうえで
printf("%x ", *cp);
は
printf("%02x ", *cp);
(「2」は unsigned char のビット数によって適宜変える) とした方が見やすいだろう.
printf("%02hhx ", *cp);
とすると型には厳密になるけど, さすがに変態すぎると思う.
No.2
- 回答日時:
ちょうど2のべき乗の値(1,2,4,8,16,32,,,,)の場合は、2進数整数で表すと1の後に0が何個か並んだ物になるのはわかりますよね?
浮動小数点形式の仮数部は、先頭の1を省略するので、2のべき乗の値の浮動小数点仮数部はオールゼロと言うことになります。
表示は上位ビットを先に表示した方が分かり易いので、
unsigned char *cp = vp;
for (int i=7; i>=0; i--) {
printf("%02X ", cp[i]);
}
が良いかと思います。これで2.0を表示した場合、
40 00 00 00 00 00 00 00
となりますが、16進16桁のうち、先頭の16進3桁が符号部と指数部で、残り13桁が仮数部です。
2.0は2の1乗で指数は1ですが、これに1023を足した物が倍精度浮動小数点の仮数部なので、10進の1024を16進表示した0x400が指数部です。
正の値なので、符号ビットは0。
仮数部は上述のようにオールゼロ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
【教えて!goo ウォッチ 人気記事】風水師直伝!住まいに幸運を呼び込む三つのポイント
記事を読む>>
-
Cの関数の引数のconst *charについて
C言語・C++・C#
-
Cのオブジェクトファイルの逆アセンブル
C言語・C++・C#
-
関数ポインタの高速化のメリット
C言語・C++・C#
-
-
4
変数のスコープ
C言語・C++・C#
-
5
C言語でif文が予想と違う動きをする件について7
C言語・C++・C#
-
6
const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか
C言語・C++・C#
-
7
マクロ関数 #define の効果は何ですか? わかりやすく教えて下さい
C言語・C++・C#
-
8
int16_t の _t は何?
C言語・C++・C#
-
9
C言語 コマンドプロンプトについて。
C言語・C++・C#
-
10
アセンブラ指令
C言語・C++・C#
-
11
いまc言語の標準ライブラリ文字列を勉強しているのですがいまいちわかりません。 strcmpとmemc
C言語・C++・C#
-
12
プログラミング c言語
C言語・C++・C#
-
13
プログラミング 素数か素数ではないか判断するプログラミングで、写真のようなプログラミングを打ったとき
C言語・C++・C#
-
14
略語の読み方について
C言語・C++・C#
-
15
C言語でファクト関数を使わずに階乗を計算する方法はありますか?できれば教えてください
C言語・C++・C#
-
16
Cのコンパイルでコメントアウトをそのままオブジェクトに保持したい
C言語・C++・C#
-
17
Javaって使いますか、もう古いですか?C++とどっちがいいですか?分析でC++使う授業ありましたけ
C言語・C++・C#
-
18
visual studio 2019において、宣言していない変数があるのにエラーなくビルド出来ました
C言語・C++・C#
-
19
c言語
C言語・C++・C#
-
20
プログラミング 2つの整数を読み込んで、等しければ 「二つの値は同じです」と表示し、そうでなければ,
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
strcmp
-
4の倍数を論理演算で表す。。
-
switch分のケースを範囲数?に...
-
【C言語教えてください】sin波...
-
テキストカーソル位置の取得
-
%P と %X の違い
-
C言語での、年複利の計算方法...
-
10個出力で改行したいのですが...
-
二つの整数値の大小比較
-
C言語で、「自然数nを入力し、n...
-
cshの文字列操作(0埋め)
-
ガウスの消去法、後退代入について
-
printfの出力内の文字をdefine...
-
defineで定数が置き換えられな...
-
文字を動かしたい
-
ifなんですが
-
コマンドプロンプトがすぐ消える
-
入力したお金の金額からお札の...
-
if文がコンパイルエラーを起こ...
-
円の面積を求めるプログラミン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
printf で二進表示を行いたい。
-
10個出力で改行したいのですが...
-
コンパイルエラーについて
-
4の倍数を論理演算で表す。。
-
unsigned int型について
-
c言語でAからZまでを表示する...
-
cshの文字列操作(0埋め)
-
テキストカーソル位置の取得
-
%P と %X の違い
-
【C言語教えてください】sin波...
-
scanfに文字が入力されたときに...
-
コマンドラインに出力した文字...
-
printf( " %2d", p * q );
-
ホームページをC言語で作りたい...
-
strcmp
-
C言語
-
defineで定数が置き換えられな...
-
printfの出力内の文字をdefine...
-
error C2143: 構文エラー : ';'...
-
CTRL+Dでループを抜けるには
おすすめ情報