実数型のデータと計算 (本ページは本学情報通信工学科伊藤先生の作成されたページを元にしています)
実数型のデータ
実数の表記法
実際の数値計算においては,整数型のデータだけではなく,小数や非常に大きい(小さい)数を取り扱 う必要が生じる(例えば,円周率など).
普通の実数の書式
3.141592
-0.01234
このくらいの小数であればこのままプログラム中に書き込んでも良いが,
非常に大きな実数
602000000000000000000000.0 アボガドロ数
これでは,あまりにも不便な表示法であるので一般には
6.02×1023
という指数表記を用いる.6.02 の数字の部分を仮数部,23 の数字の部分を指数部と呼ぶ.しかし,計算機の中ではこのままの形で表示が出来ないため,
6.02e23 または 6.02e+23, 6.02E23
として表現される.
コンピューターの内部では,実数はその大きさにかかわらず,すべて指数形式で記憶されている.
コンピューターにとっては,以下の3つの実数は全く同じものとなる.
12.345
0.12345e2
1234.5e-2
これらの表示においては,小数点の位置は指数部によって変化する.このような表記法を浮動小数点型と言う.上の3つの小数において重要な事は,すべて仮数部が5けたの有効数字で表示されている事である.
C-言語においては,実数型のデータとして float 型 と double型 が存在する.
実際の計算において,これらの型を使い分ける理由は,仮数部の数字において,double型はfloat 型の2倍(double)の有効数字が使えるためである.一般のコンピュータでは,float 型は7桁の有効数字,double型は15桁の有効数字があり,float 型を単精度実数,double型を倍精度実数と呼ぶ.
プログラム中の実数はすべて倍精度で統一してしまえば良い.これは有効数字の桁数の問題であり,ほとんどのプログラマーはそうしている.ただ,プログラムの中で非常に多くの実数配列( array[100][100][100] など)が必要な時などには,必要となるメモリーを減らすために単精度に定義する必要が生じる.
実数型変数の宣言
double pai;
pai=3.141592654;
整数型変数の場合と全く同様である.
実数型の四則演算は,整数型と同様に定義されている.ただし,次に説明する代入文と型変換には十分に注意する必要がある.
代入文と型変換
C-言語のコンパイラにとっては,代入文の左辺と右辺は同じデータ型でなくてはいけない.
int int_num;
double double_num;
という変数の宣言のもとで,
(整数型変数)=整数型データ
int_num=3;
(倍精度型実数変数)=倍精度型データ
double_num=3.141592654;
は正常に行なわれる.
しかし,左辺と右辺でデータ型が揃わない場合には,暗黙の型変換がコンパイラーによって行なわれる.つまり,
(整数型変数)=倍精度型データ
int_num=3.141592654;
においては,まず右辺の倍精度データが整数型データに変換され,3 となり,小数点以下は切り捨て(四捨五入ではない!)られた後で,int_num に代入される.
また,逆のケースである
(倍精度型実数変数)=整数型データ
double_num=3;
では,右辺の整数型データの3を倍精度データの3.e0 に変換後,代入される.
すべての整数型データは,倍精度型実数データに変換されるが,逆の場合は必ずしも可能とは限らない.
int_num= 8.0e30;
この場合整数型データの最大数を超えてしまう.このことを,倍精度型実数データは整数型データより大きな型である,または,整数型データは倍精度型実数データより小さな型であると言う.
型変換の原則1:小さな型への型変換は十分の注意が必要である.
プログラム例(教科書143ページ,例7.2の変形)
/****************
ex7_2.c
学生番号:
氏名:
****************/
#include <stdio.h>
main()
{
short short_num;
long long_num;
float float_num;
double double_num;
long_num=1234567891;
short_num=long_num;
float_num=long_num;
double_num=long_num;
printf("long : %ld¥n", long_num);
printf("short: %d¥n", short_num);
printf("float: %f¥n", float_num);
printf("double: %lf¥n", double_num);
exit(0);
}
printf 文中の制御文字 "%ld", "%lf" はlong型の整数変数および倍精度型変数をlong digit (整数),long float という形式で出力する.
練習1:上のプログラムをファイルに作成し,コンパイル,実行せよ.実行結果を見て,なぜそうなったかを考察せよ.
四則演算と型変換
int int_num;
double double_num;
float answer;
という宣言の下で以下の様な演算はどのように行なわれるのか?
answer= int_num + double_num;
型変換の原則2:2項演算では,2つの項のうちデータ型の大きい方にあわせて型変換が行なわれ,実行される.
上の例では,右辺の足し算は,int_numをdoubleに型変換をして,足し算を行ない,このdouble型のデータを,左辺のデータ型であるfloat型に変換して代入される.この2つの型変換の原則を忘れないように.
危険をはらんでいるプログラム例:
int count;
double base, answer;
count=5;
base=1.0;
answer=base + count / 2;
最終行の演算は,まず count / 2 という二項演算を行なう.2項ともに整数型データであるので,割り算の結果も整数型となり,2.5 という実数ではなく,2 と切り捨てられてしまう.次に,double型であるbaseとの足し算は,2をdouble型の2.e0 に型変換し,結果3.e0 が結果としてdouble型変数のanswerに代入される.
5 / 2 = 2.5 という計算をさせたければ,
answer= base + count / 2. ;
というように,2 を実数としておいてやれば良い.
キャスト演算子
以上のような,暗黙の型宣言による,予測しなかった混乱をさける為には,演算および代入文において異なるデータの型が混在することを避けることが重要.特に,小さな型への型変換が暗黙に行なわれる事は極力避けるべきである.
式の中のデータの型を強制的に揃えるためには,キャスト演算子を用いる.
(型規定子) データ
の形で指定する.例えば次のようにする.
(int)
(long)
(float)
(double)
キャスト演算子の具体的な使用例として,例えば次のように
answer= base + (double) count / (double) 2 ;
とすることで,式において全てのデータが double 型で統一されている.
プログラム例(教科書139ページ,例7.1の変形)
/****************
ex7_1.c
学生番号:
氏名:
****************/
#include <stdio.h>
main()
{
double data, answer;
data=2.0;
answer= data % 3;
printf("%lf", answer);
exit(0);
}
練習2:上のプログラムでは,2を3で割った余りの2を倍精度実数変数 answer に代入し,出力しようとしている.
上のプログラムをファイルに作成し,コンパイル,実行せよ.正常に動作するか? もし,問題がある場合には,今回の授業内容に従って,プログラムを変更し,正常動作するようにせよ.
ヒント: %演算子は実数型データには適用できない.
提出課題:正の実数を入力して,小数点以下を四捨五入して整数にした数字と元の実数の小数点以下のみの部分を出力するプログラムを作成してレポートせよ.
実行例1:
入力 3.141592
出力 3
0.141592
実行例2:
入力 3.76543
出力 4 (注意 3ではない!)
0.76543
提出要領:レポートシステムによる.
レポート名: oomoto/real
提出期限: 7月14日(土曜日)