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

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

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

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

Q&A

解決済

2回答

1030閲覧

コンピュータでのfloat

forza

総合スコア21

C

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

0グッド

0クリップ

投稿2019/02/06 03:52

C言語での質問なのですが、
十進数の 0.7 は float でどのような値になっているのでしょうか?
ご回答宜しくお願いします。

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

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

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

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

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

guest

回答2

0

2進数の小数点以下の数の表現ですが、桁の数は1を2で割ったものですんで、0.7 は
0 . >> 1
1 >> 0.5
0 >> 0.25
1 >> 0.125
1 >> 0.0625
0 >> 0.03125
以下続く

ということで、
0.10110 ...
という数値となります
10進数の0.7は2進数になると表現しきれない、というのがわかりますね

投稿2019/02/06 04:47

y_waiwai

総合スコア87747

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

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

0

ベストアンサー

C

1#include <stdio.h> 2 3int main(void) 4{ 5 float f = 0.7f; 6 unsigned int ul = *(unsigned int *)(&f); 7 8 printf("%x\n", ul); 9 printf("%f\n", f); 10 return 0; 11}

Bash

1$ gcc f.c 2$ ./a.out 33f333333 40.700000

ちょっと題意を読み違えました。。。

コンピュータにおいて、厳密に「0.7」という実数は存在し得ません。
浮動小数点数は無限にある一方、コンピュータ内部では32bitとか64bitとか、情報量に制限があることが原因です。

そこでIEEEという組織が定めた浮動小数点数をコンピュータで表現するための仕様が、IEEE754になります。

その結果のコンピュータ内でのどう扱われているか、を示すのが先に示した「0x3f333333」という値になります。

ここまでは大丈夫でしょうか。

さて、浮動小数点数にはもう一つ問題があります。表示をどこまで表示するか、です。

C言語でターミナルに文字を表示する関数と言えばprintfですね。
上記で述べたように、コンピュータ内で厳密に「0.7」という実数が存在できない以上、IEEE754に従ったデータ列を、仕様に従って表示する必要があります。

printfは一定の桁数までは表示してくれますが、これも限りがあります。
0.7という実数は0.7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
と理論上イコールである必要がありますが、こんな長い数字を表現するには結構なデータ量が必要になります。

一般的にprintfでは適当なところで切ってしまって、「ざっくり0.7」と表示しますが、以下のように桁数を増やしてやると、

C

1#include <stdio.h> 2 3int main(void) 4{ 5 float f = 0.7f; 6 unsigned int ul = *(unsigned int *)(&f); 7 double d = 0.7; 8 unsigned long long ull = *(unsigned long long *)(&d); 9 10 printf("%x\n", ul); 11 printf("%.25f\n", f); 12 13 printf("%llx\n", ull); 14 printf("%.25lf\n", d); 15 return 0; 16}

(ついでにdoubleも増やしてみました。)

Bash

1$ gcc f.c && ./a.out 23f333333 30.6999999880790710449218750 43fe6666666666666 50.6999999999999999555910790

厳密な0.7からはズレていることが分かります。

投稿2019/02/06 03:59

編集2019/02/06 04:25
kazto

総合スコア7196

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

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

forza

2019/02/06 04:34

早々のご回答を有難う御座いました。 悩んでいたところ的確なご回答を頂けて納得し満足致しました。 とても助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問