● 講義資料
★ 浮動小数点数の表現
仮数部2桁,指数部−1≤e≤1の2進浮動小数点数で表すことができる数.
0=0.00
q
1/8=0.01×2−1
a
2/8=0.10×2−1
a
3/8=0.11×2−1
a
−1/8=−0.01×2−1
a
−2/8=−0.10×2−1
a
−3/8=−0.11×2−1
a
4/8=1.00×2−1
q
−4/8=−1.00×2−1
q
5/8=1.01×2−1
q
−5/8=−1.01×2−1
q
6/8=1.10×2−1
q
−6/8=−1.10×2−1
q
7/8=1.11×2−1
q
−7/8=−1.11×2−1
q
4/4=1.00×20
q
−4/4=−1.00×20
q
5/4=1.01×20
q
−5/4=−1.01×20
q
6/4=1.10×20
q
−6/4=−1.10×20
q
7/4=1.11×20
q
−7/4=−1.11×20
q
4/2=1.00×21
q
−4/2=−1.00×21
q
5/2=1.01×21
q
−5/2=−1.01×21
q
6/2=1.10×21
q
−6/2=1.10×21
q
7/2=1.11×21
q
−7/2=−1.11×21
q
Underflow
subnormal e=−1
e=−1 e= 0
e= 0
e= 1 e= 1
overflow- overflow
この浮動小数点数の体系で表現できる数は,図のなかの黒円で示したものに限られる. “subnormal”
と示した数は,有効桁が少なくなっていることに注意.
したがって, 1/2 + 1/8 = 5/8と正確に計算することが可能であるが, 1/2 + 1/16は正確な計算 ができないことがわかる.
★
ASCII
コード表0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
0 NULL DLE SP 0 @ P ‘ p
1 SOH DC1 ! 1 A Q a q
2 STX DC2 " 2 B R b r
3 ETX DC3 # 3 C S c s
4 EOT DC4 $ 4 D T d t
5 ENQ NAK % 5 E U e u
6 ACK SYN & 6 F V f v
7 BEL ETB ’ 7 G W g w
8 BS CAN ( 8 H X h x
9 HT EM ) 9 I Y i y
A LF SUB * : J Z j z
B VT ESC + ; K [ k {
C FF FS , < L \ l |
D CR CS - = M ] m }
E SO RS . > N ^ n _
F SI US / ? ) _ o DEL
1. 以下のex04-1.cを入力してコンパイルおよび実行を行ってみよう.
• 整数型変数の除算は「商」が得られる.
• 整数型変数同士の除算を浮動小数点数に代入しても「商」が得られる. すなわち, 右辺の
「式の値」が左辺の変数に代入される.
• 算術演算の被演算子の片方が浮動小数点型の時には, 浮動小数点型としての演算が行われ る. すなわち,算術演算では「算術変換」が行われている.
• 明示的な型変換(cast)によって「式の値の型」を変更できる.
2. 以下のex04-2.cを入力してコンパイルおよび実行を行ってみよう.
• 正の整数の除算は予想通りの結果を得ることができる.
• 除算において,少なくとも一方の被演算子が負の場合には,除算の結果および余りの結果の 符号は処理系依存となる. したがって,負の数を被演算数に持つ除算(または余り)を行っ てはいけない.
• 負の数に関係する除算で保証されることは, – (a/b)*b+a%b=aが成り立つ.
– 余りの絶対値は除数の絶対値より小さい.
の2点のみである.
3. 以下のex04-3.cを入力してコンパイルおよび実行を行ってみよう.
• 浮動小数点数の演算には誤差がある.
• 特に0.1は2進浮動小数点表示では誤差があり,0.1の10回の加算が 1.0になるわけで はない.
• double型変数の有効桁数は2進で53桁程度であるため,10進での有効桁数は16桁程
度となる.
4. 以下のex04-4.cを入力してコンパイルおよび実行を行ってみよう.
• char型変数を「整数型変数」として評価する際には「整数への格上げ」が行われる.
• char 型変数は「符号付き」か「符号無し」かは処理系依存であり, 符号付きの場合には,
「整数への格上げ」の時点で「符号拡張」が行われる可能性がある. なお, 「符号拡張」が 行われるかどうかは処理系依存である.
• したがって,char型変数に「負の数」を代入する場合には,必ずunsigned char型を用い なければいけない.
5. 以下のex04-5.cを入力してコンパイルおよび実行を行ってみよう.
• sizeof演算子によって,各型が占めるメモリ内での「バイト数」を得ることができること.
• C言語における「バイト数」とは,char型変数の占めるビット数を1バイトとして定義さ れている.
電子メールで「今日の講義の感想や意見」を送ってください.
★
ex04-1.c
の内容
/* ex04-1.c */
/* 除算 */
#include <stdio.h>
int i, j, k, l ; double x, y, z ;
int main(int argc, char **argv) {
i = 3 ; j = 2 ; k = i/j ; l = i%j ;
printf("%d/%d = %d, modulo %d\n", i,j,k,l) ;
z = i/j ;
printf("%d/%d = %f\n", i,j,z) ;
x = 3.0 ; y = 2.0 ; z = x/y ;
printf("%f/%f = %f\n", x,y,z) ;
z = i/y ;
printf("%d/%f = %f\n", i,y,z) ;
z = x/j ;
printf("%f/%d = %f\n", x,j,z) ;
z = (double)i/j ;
printf("%d/%d = %f\n", i,j,z) ;
z = i/(double)j ;
printf("%d/%d = %f\n", i,j,z) ;
z = (double)(i/j) ;
printf("%d/%d = %f\n", i,j,z) ;
return 0 ; }
/* 負の数に関する除算 */
#include <stdio.h>
int i, j, k, l ;
int main(int argc, char **argv) {
i = 3 ; j = 2 ; k = i/j ; l = i%j ;
printf("%d/%d = %d, modulo %d\n", i,j,k,l) ;
i = 3 ; j = -2 ; k = i/j ; l = i%j ;
printf("%d/%d = %d, modulo %d\n", i,j,k,l) ;
i = -3 ; j = 2 ; k = i/j ; l = i%j ;
printf("%d/%d = %d, modulo %d\n", i,j,k,l) ;
i = -3 ; j = -2 ; k = i/j ; l = i%j ;
printf("%d/%d = %d, modulo %d\n", i,j,k,l) ;
return 0 ; }
★
ex04-3.c
の内容
/* ex04-3.c */
/* 浮動小数点数の加減算 */
#include <stdio.h>
double x, y=0.1, z = 0.5 ;
int main(int argc, char **argv) {
/* 0.0 に 0.1 を10回加算する */
x = 0.0 ;
x += y ; x += y ; x += y ; x += y ; x += y ; x += y ; x += y ; x += y ; x += y ; x += y ; printf("%.16e\n", x) ;
/* 1.0 から 0.1 を10回減算する */
x = 1.0 ;
x -= y ; x -= y ; x -= y ; x -= y ; x -= y ; x -= y ; x -= y ; x -= y ; x -= y ; x -= y ; printf("%.16e\n", x) ;
/* 0.0 に 0.5 を2回加算する */
x = 0.0 ;
x += z ; x += z ; printf("%.16e\n", x) ;
/* 1.0 から 0.5 を2回減算する */
x = 1.0 ;
x -= z ; x -= z ; printf("%.16e\n", x) ;
return 0 ; }
/* 文字型変数と整数への格上げ */
#include <stdio.h>
char c ;
unsigned char d ;
int main(int argc, char **argv) {
c = 0x61 ; /* c = ’a’ */
printf("c = %c\n", c) ; printf("c = %d\n", c) ; printf("c = %X\n", c) ; printf("\n") ;
c = 0x80 ;
printf("c = %d\n", c) ; printf("c = %u\n", c) ; printf("c = %X\n", c) ; printf("\n") ;
d = 0x80 ;
printf("d = %d\n", d) ; printf("d = %u\n", d) ; printf("d = %X\n", d) ; printf("\n") ;
printf("%d\n",c-d) ; return 0 ;
}
★
ex04-5.c
の内容
/* ex04-5.c */
/* いろいろな型の変数のサイズ */
#include <stdio.h>
int main(int argc, char **argv) {
printf("char:\t%lu\n", sizeof(char)) ; printf("short:\t%lu\n", sizeof(short)) ; printf("int:\t%lu\n", sizeof(int)) ; printf("long:\t%lu\n", sizeof(long)) ; printf("float:\t%lu\n", sizeof(float)) ; printf("double:\t%lu\n", sizeof(double)) ;
printf("long double:\t%lu\n", sizeof(long double)) ; return 0 ;
}
号付き整数と符号無し整数がある.
• 計算機内部での整数は,最大値と最小値を持ち,最大値を越える計算結果は一般には保証されない.
• 負の整数は2の補数による表現で表されることが多い.
• C言語では整数を表す変数の型として intがある.
• C言語では,変数は利用する前に宣言(定義)を行わなければならない.
● 前回の実習の解説
• int型の「正の最大の整数」を定数として代入する場合には, i = 0x7fffffff ;
として16進定数で代入すべきである. これを10進定数で i = 2147483647 ;
と書くと,1文字が異なっていてもそれに気が付くとは限らない.
• より正しくは,このような「システムに依存した定数値」を用いるときには,
#include <stdio.h>
#include <limits.h>
int main(int argc, char **argv) {
int i=INT_MAX ; printf("%d\n",i) ; return 0 ;
}
のように「システムヘッダファイル」(この場合はlimits.h)を用いて,INT_MAXのようなあらかじ め定義された値を用いることが望ましい.