93
7 実数データの扱い
• 実数計算,
• 整数と実数の混合演算,キャスト演算,
• 実数データの入出力—%f, %e, %g—,
• 数学関数の利用,
• コンパイルはどの様に進むか?,
• 誤差の発生とその対策
色々な形に構成された処理手順をC言語でどの様に表すかということに焦点を当てる ために、これまで整数データ(int型)しか扱って来なかったが、この節と次の節では実数 データの扱いを中心に述べる。
3 /* を出力するCプログラム */
4 /* ---double型で計算する版--- */
5 #include <stdio.h>
6 #define PI (3.1415926535897932) /* 円周率 */
7 int main(void) 8 {
9 double r, h;
10 scanf("%lf%lf", &r, &h);
11 printf("底面の半径が %f, 高さが %f の円錐の体積\n = %f\n", 12 r, h, PI*r*r*h/3.0);
13 return 0;
14 }
[motoki@x205a]$ gcc volume-of-cone-double.c Enter [motoki@x205a]$ ./a.out Enter
2.0 5.0 Enter
底面の半径が 2.000000, 高さが 5.000000 の円錐の体積
= 20.943951 [motoki@x205a]$
ここで、
• プログラムの6行目 は、Cのソースコードを機械語に翻訳する前に、以降に出て来る PI という名前を全て (3.1415926535897932) という文字列に置き換えることを指示
する。 [こういった名前, 行を各々マクロ(名), マクロ定義と言う。]
• プログラムの6行目 の3.1415926535897932 はdouble型の実数値定数を表す文字列 である。コンピュータの機種にも依存するが、double 型では52ビット,15〜16桁の 有効桁を保持することが多いため、ここでは17桁分の精度で指定した。
• プログラム9行目 は、2つのdouble型データのための変数領域を確保し、それぞれ r, h と名付けることをコンパイラに知らせる宣言文である。double型は実数を表
すための(標準の)倍の精度の内部表現形式に対応したデータ型である。
• プログラム10行目 の入力書式中の %lf は読み込んだデータを double型(倍精度実 数型)の内部表現形式に変換して、別途指定された記憶領域に格納することを指示し
ている。 #
" !
補足:
%fだとfloat型(単精度実数型) の内部表現形式に変換される。
%lfの中のlは「long」の意。
• プログラム11行目 の出力書式中の%f は、別途指定された式の値がdoubleまたは
float型の内部表現形式に従っていると仮定して、これを10進の文字列に変換して、
この%fの場所に出力することを指示する。%lfではなく%f となっているが、これは 誤りではない。printfの場合はscanfの場合と違って、実数値を出力する際に l とい う拡張子は付けない。
7.1. 実数計算 95
'
&
$
% 補足:
float型のデータがprintfの引数として指定されていた場合、
そのデータはdouble型に変換されてからprintfに渡される。
このため、実数データの出力書式を指定する際には“l”という 拡張子は全く意味を為さない。 付けても無視されるだけ?
• プログラムの12行目 の 3.0はdouble型の実数値定数を表す文字列である。
float型で処理するプログラム:
実数データ r, h をそれぞれ r, hという名前のfloat型 変数に読み込みfloat型で体積 の計算を行うCプログラムと、これをコンパイル/実行している様子を次に示す。(下線部 はキーボードからの入力を表す。)
[motoki@x205a]$ nl volume-of-cone-float.c Enter
1 /* 2つの実数データ r と h を読み込み、 */
2 /* 底面の半径が r、高さが h の円錐の体積 */
3 /* を出力するCプログラム */
4 /* ---float型で計算する版--- */
5 #include <stdio.h>
6 #define PI (3.1415926f) /* 円周率 */
7 int main(void) 8 {
9 float r, h;
10 scanf("%f%f", &r, &h);
11 printf("底面の半径が %f, 高さが %f の円錐の体積\n = %f\n", 12 r, h, PI*r*r*h/3.0f);
13 return 0;
14 }
[motoki@x205a]$ gcc volume-of-cone-float.c Enter [motoki@x205a]$ ./a.out Enter
2.0 5.0 Enter
底面の半径が 2.000000, 高さが 5.000000 の円錐の体積
= 20.943950 [motoki@x205a]$
ここで、
• プログラムの6行目 の 3.1415926f はfloat型の実数値定数を表す文字列である。
double型定数と区別するために最後にf という文字が付いている。コンピュータの
機種にも依存するが、float型では23ビット,6〜7桁の有効桁を保持することが多い ため、ここでは8桁分の精度で指定した。
• プログラム9行目 は、2つのfloat型データのための変数領域を確保し、それぞれr, h と名付けることをコンパイラに知らせる宣言文である。float型は実数を表すため の単精度の内部表現形式に対応したデータ型である。
• プログラム10行目 の入力書式中の %f は読み込んだデータを float型(単精度実数 型) の内部表現形式に変換して、別途指定された記憶領域に格納することを指示して いる。
• プログラム11行目 の出力書式中の%f は、別途指定された式の値がdoubleまたは
float型の内部表現形式に従っていると仮定して、これを10進の文字列に変換して、
この%fの場所に出力することを指示する。
• プログラムの12行目 の 3.0fはfloat型の実数値定数を表す文字列である。double 型定数と区別するために最後にf という文字が付いている。
□演習 7.2 (円の面積) 1つの実数データを変数 r に読み込み、
半径が r の円の面積
を出力するCプログラムを作成せよ。
□演習 7.3 (べき乗) 実数データ a と非負整数データk を読み込み、ak を計算して出力 するCプログラムを作成せよ。 但し、ここでは簡単のため00 = 1 と考えよ。
実数データ間の算術演算: 実数データ間では剰余演算子 % が使えないことを除いて、
整数データの場合と同じである。 すなわち、次の算術演算子が使える。
算術演算子 機能
+ 加算。但し、単項演算の場合は恒等変換を表す。
- 減算。但し、単項演算の場合は符号反転を表す。
* 乗算。
/ 除算。
浮動小数点定数:
• 123.4, 123., .4, 123.4e5, .4E+5, 123e-5, ... といった書き方が出来る。 これらは double型の定数で、それぞれ 123.4,123.0,0.4,123.4×105,0.4×105,123×10−5, ...を 表す。
• 定数をfloat型にしたければ、最後に f またはF という接尾語を付ける。 例えば、
123.4f, .4E+5F, ... 。
• 定数をlong double型にしたければ、最後にlまたは Lという接尾語を付ける。 例 えば、123.4l, .4E+5L, ... 。
数字
.
数字 指数部浮動型限定
数字
.
指数部 浮動小数点数定数
+
数字
− 指数部 e
E
浮動型限定
L l F f