★基本制御文(while17)★


それでは、除算を減算で行うプログラムを考えてみましょう。

乗算は加算を繰り返すことで出来ました。

除算は減算を繰り返すことで出来ます。


13÷4を考えてみます。

13÷4の答えは「3.25」ですが、小数以下を考えると難しくなるので、「商と余り」という形で計算します。

13÷4の商は3、余りは1です。


これを減算を繰り返す方法で考えてみると、

13−4=9

 9−4=5

 5−4=1

この時点で1から4を減算するとマイナスになりますので、計算を止めます。

減算は3回行っています。

最後の計算の答えは1です。

これが商と余りになります。

最初はマイナス等は考慮しなくて構いませんので、考えてみてください。

<実行結果>

元の数を入力してください:13
割る数を入力してください:4
商は3、余りは1です。
続行するには何かキーを押してください・・・









































解答例です。


<sample program 044-01>

#include <stdio.h>

int main(void)
{
    int input1;
    int input2;
    int syou;
    int amari;

    printf("元の数を入力してください:");
    scanf("%d", &input1);

    printf("割る数を入力してください:");
    scanf("%d", &input2);

    syou = 0;

    amari = input1;

    while (amari >= input2) {
        amari -= input2;
        syou++;
    }

    printf("商は%d、余りは%dです。\n", syou, amari);

    return 0;
}

<実行結果>

元の数を入力してください:13
割る数を入力してください:4
商は3、余りは1です。
続行するには何かキーを押してください・・・

商は減算した回数を数えれば良いですから、カウンタですね。

余りは元の数から減算を繰り返し、これ以上引くとマイナスになる、という数値です。

合計の逆で、変数「amri」に元の数「input1」を入れておいて、

amari -= input2;

で、どんどん減算していきます。

繰り返し条件は、

while (amari >= input2) {

となっていますので、

amariがinput2より小さくなったら、繰り返しを終了します。

※amariとinput2が同じ時は、まだ減算できます。


では、別の数値を入力してテストを行ってみましょう。

<実行結果>

元の数を入力してください:4
割る数を入力してください:5
商は0、余りは4です。
続行するには何かキーを押してください・・・

元の数より割る数を大きくしてみましたが、正しく結果が表示されました。


では「0」を使ってみましょう。

<実行結果>

元の数を入力してください:0
割る数を入力してください:5
商は0、余りは0です。
続行するには何かキーを押してください・・・

元の数を「0」にすると、正しく結果が出ています。


では、割る数に「0」を入れてみます。

<実行結果>

元の数を入力してください:5
割る数を入力してください:0

終わらなくなりました・・・

元の数から割る数を減算していきますが、「0」を減算していますから、いつまでたっても元の数が減らないのです。

では、応急処置を・・・と言いたい所ですが、「0」で割るというのは元々コンピュータでは出来ないのです。

下のプログラムを実行してみてください。


<sample program 044-02>

#include <stdio.h>

int main(void)
{
    int data;

    data = 10;

    printf("%d\n", data / 0);

    return 0;
}

<実行結果>


エラーになりました。

よく見ると、コンパイルした時に警告(warning)が出ています。

  warning C4723: 除算の2番目のオペランドは、コンパイル時に 0 と評価され、不定の結果を返します。

「除算の2番目のオペランド」とは、除算の右辺のことです。

なぜ、このような警告が出るのか説明します。


ゼロディバイド(ゼロ除算)


ゼロ除算については、以前に少し書きました。

1÷0.1の答えはいくつでしょう?

「10」ですね。

1÷0.01は?

「100」です。

1÷0.001は?

「1000」です。

このまま、右辺をず〜っとゼロに近づけていくと、答えはどんどん大きくなっていきます

つまり、ゼロで割ると答えが無限大となってしまい、コンピュータでは計算出来ないのです。


では、除算のプログラムに戻って、ゼロ除算を回避するプログラムを考えてみましょう。









































解答例です。


<sample program 044-03>

#include <stdio.h>

int main(void)
{
    int input1;
    int input2;
    int syou;
    int amari;

    printf("元の数を入力してください:");
    scanf("%d", &input1);

    printf("割る数を入力してください:");
    scanf("%d", &input2);

    if (input2 != 0) {

        syou = 0;

        amari = input1;

        while (amari >= input2) {
            amari -= input2;
            syou++;
        }

        printf("商は%d、余りは%dです。\n", syou, amari);
    }
    else {
        printf("ゼロ除算エラー\n");
    }

    return 0;
}

<実行結果>

元の数を入力してください:5
割る数を入力してください:0
ゼロ除算エラー
続行するには何かキーを押してください・・・

割る数(input2)が「0」の場合、計算をせず「ゼロ除算エラー」と表示します。


では、マイナスへの対処を考えてみましょう。

乗算では、右辺がマイナスの場合を考えればよかったのですが、除算の場合両辺とも考慮する必要があります。

  −8÷4

−8から4を減算するとマイナスが増加していきます。

  8÷−4

8から−4を減算するとどんどん増えていきます。

  −8÷−4

−8から−4を減算すると2回で0になると思いますが、実際には繰り返し条件が、

amari = input1;

while (amari >= input2) {

となっているため、最初から繰り返し条件が不成立となり、一度も繰り返されずに終了します。


色々と効率の良い方法はありそうですが、前回の乗算で使った「minus_flag」を利用して考えてみてください。









































解答例です。


<sample program 044-04>

#include <stdio.h>

int main(void)
{
    int input1;
    int input2;
    int syou;
    int amari;
    int left_minus_flag;
    int right_minus_flag;

    printf("元の数を入力してください:");
    scanf("%d", &input1);

    left_minus_flag = 0;

    if (input1 < 0) {
        left_minus_flag = 1;
        input1 = -input1;
    }

    printf("割る数を入力してください:");
    scanf("%d", &input2);

    right_minus_flag = 0;

    if (input2 < 0) {
        right_minus_flag = 1;
        input2 = -input2;
    }

    if (input2 != 0) {

        syou = 0;

        amari = input1;

        while (amari >= input2) {
            amari -= input2;
            syou++;
        }

        if (left_minus_flag == 1) {
            syou = -syou;
        }

        if (right_minus_flag == 1) {
            syou = -syou;
        }

        printf("商は%d、余りは%dです。\n", syou, amari);
    }
    else {
        printf("ゼロ除算エラー\n");
    }

    return 0;
}

<実行結果1>

元の数を入力してください:-8
割る数を入力してください:4
商は-2、余りは0です。
続行するには何かキーを押してください・・・

<実行結果2>

元の数を入力してください:8
割る数を入力してください:-4
商は-2、余りは0です。
続行するには何かキーを押してください・・・

<実行結果3>

元の数を入力してください:-8
割る数を入力してください:-4
商は2、余りは0です。
続行するには何かキーを押してください・・・

右辺か左辺がマイナスの場合、商はマイナスになり、右辺も左辺もマイナスの場合、商はプラスになります。

では、次回は累乗(べき乗)を乗算の繰り返しで行うというプログラムを作ってみましょう。


次へ

戻る

目次へ