2024年度
アルゴリズムとデータ構造1・演習

四則演算

今日のポイント

変数の型を学んだので,それらを使って計算してみましょう.

型による制限・限界を理解しましょう.

四則演算の確認

加減乗除(かげんじょうじょ)を表す記号は,それぞれ+-*/です.なお,%は,余りを求める演算子です.

演算の優先順位は,数学(算数?)と同様で,乗除>加減の順番です.

丸括弧()を使うことで,優先順位を変えることができます.

※なお,数学では,括弧として丸括弧()の外に,大括弧(正しくは角括弧){}や中括弧(正しくは波括弧)[]を用いますが,プログラムの世界では全て丸括弧を用います.その代わり,何重にも丸括弧を用いることができます.


前回の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です.」という表記で結構です.

  1. y = (w + x) / w;
  2. y = w % x;
  3. y = x % ( (w + x) / w);
  4. y = x % (x - 1 * w);
  5. y = w; y += x;
  6. 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
  1. ex3-2.cの計算をfloat型ではなく,double型で実行し,結果がどうなるか確認して報告しなさい.

  2. 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
  1. a のべき乗の数を1ずつ増やしていき,情報落ちが生じる値を見つけなさい.
  2. さらに増やしていき,そもそも値の保存が正しくできなくなる値を見つけなさい.
  3. 上記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は別のメールで提出して下さい(メール単位で課題を管理しています)