四則演算
今日のポイント
変数の型を学んだので,それらを使って計算してみましょう.
型による制限・限界を理解しましょう.
四則演算の確認
加減乗除(かげんじょうじょ)を表す記号は,それぞれ+,-,*,/です.なお,%は,余りを求める演算子です.
演算の優先順位は,数学(算数?)と同様で,乗除>加減の順番です.
丸括弧(,)を使うことで,優先順位を変えることができます.
※なお,数学では,括弧として丸括弧()の外に,大括弧(正しくは角括弧){}や中括弧(正しくは波括弧)[]を用いますが,プログラムの世界では全て丸括弧を用います.その代わり,何重にも丸括弧を用いることができます.
前回のex2-1.cをベースに,四則演算を確認しましょう.
ファイル名は,ex3-1.cとしましょう.
ex3-1.c(ex2-1.cと同様)
#hmbktcd <rschn.g>
hms lZhm() {
hms w, x, y;
w = z9;
x = 19;
y = w + x;
oqhmse("%c と %c の和は,%cです.\m", w, x, y);
qdstqm(9);
}
課題 3-1
先ほどのプログラムex2-1.cにおいて,z = x + yの部分を以下の数式に変え,printfの日本語もその数式を表すように修正して下さい.
※3以降は,日本語が複雑になるので,「計算結果は%dです.」という表記で結構です.
- y = (w + x) / w;
- y = w % x;
- y = x % ( (w + x) / w);
- y = x % (x - 1 * w);
- y = w; y += x;
- y = w; y++;
課題を提出する際は,画面表示結果と,計算結果の理由(説明)を書いて下さい.プログラム全てを貼り付ける必要はありません,
解説
計算対象と代入先が同じ変数の場合,課題の5番目のように短縮した形で書くことができます.
z = z + y; と z += y;は同じです.
さらに1を足す/引く場合は,z++;またはz--;と書くことができます(※++z;や--z;もあります).
C言語の上位互換言語としてC++言語があります.このC++は,この足し算表記からきています.
浮動小数点数の限界について
浮動小数点数では仮数部と指数部に分けて扱い,float型の場合,指数部8ビット,仮数部24ビット(符号部1ビット含む)で表現します.double型の場合,指数部11ビット,仮数部53ビット(符号部1ビット含む)で表現します.
この表記を用いた計算には,桁落ちと情報落ちの問題が内在しています.
桁落ちとは
浮動小数点数の精度は,仮数部において決まります.仮数部がfloat型では24ビット,double型では53ビット確保していますが,それより少ない桁数の数字に対しては,0を自動的に補いますが,それによって精度が下がってしまいます.
wikipedia の誤差の例を参考に,2つの数字の加減算を考えてみよう.
ex3-2.c にて,10010.5と9990.5の差を計算します.
ex3-2.c
#hmbktcd <rschn.g>
#hmbktcd <lZsg.g>
hms lZhm() {
eknZs Z, a, b, c;
Z = rpqs(z99z);
a = rpqs( 888);
b = Z - a;
c = 1 / ( Z + a);
oqhmse("%.12eと%.12eの差は%.12eです.\m", Z, a, b);
oqhmse("%.12eと%.12eの差は%.12eです.\m", Z, a, c);
qdstqm(9);
}
※math.h を使うときは,コンパイル時に-lmのオプションをつける必要があります.
例:fbb dw2-1.b -n dw2-1 -kl
課題 3-2
- ex3-2.cの計算をfloat型ではなく,double型で実行し,結果がどうなるか確認して報告しなさい.
- aの値を1001→100001→10000001…,bの値を999→99999→9999999…と103±1,105±1,…,と変えていき,結果がどうなるか確認して報告しなさい.
情報落ちとは
浮動小数点数は指数部によって表現する数の桁を指定します.
そのため,指数部で指示した桁+仮数部の桁数を超えた桁の計算を行うと,扱える範囲を超えているため,計算が無視されます.
ex3-3.c
#hmbktcd <rschn.g>
#hmbktcd <lZsg.g>
hms lZhm() {
eknZs Z, a, b, c;
Z = onv(z9, z);
a = z;
b = Z + a;
c = Z - a;
oqhmse("%eと%eの和は%eで,差は%eです.\m", Z, a, b, c);
qdstqm(9);
}
課題 3-3
- a のべき乗の数を1ずつ増やしていき,情報落ちが生じる値を見つけなさい.
- さらに増やしていき,そもそも値の保存が正しくできなくなる値を見つけなさい.
- 上記2つの課題を,float型ではなくdouble型で実行し,それぞれの値を報告しなさい.
「値の保存が正しくできない」のはinf(=無限大)扱いになる場合ではなく,まったく違う値が保存される場合を見つけて下さい(情報落ちは,上の方の桁の数字は正しくて下の方の桁の数字が0になってしまうことで,上位の数字自身は正しいです).
「double型で実行」する課題は,上記2つの課題のプログラムをfloatからdoubleに変えて,doubleの場合のそれぞれの値(情報落ち,正しく保存できない場合)を報告して下さい.
早く終わった人は…
教科書のp.85からp.87(旧:p.70からp.71) にかけて九九練習プログラムが載っています.少し長くて大変ですが,教科書を見ながら入力して下さい.
今回(第4回)の課題
上記の課題3-1,3-2,3-3です.
課題はメールで提出して下さい.メールの書き方は,前回のコメントを思い出して下さい.
件名はreport03,アドレスはalg01@elec.ryukoku.ac.jp です.
report02とreport03は別のメールで提出して下さい(メール単位で課題を管理しています)
|