🖥️

【C言語超入門】 第06回 浮動小数点数の四則演算

2024/12/25に公開

https://youtu.be/Vj1OKK9-7Yo

四国めたん
\textcolor{pink}{四国めたん: }教師役ですわ

ずんだもん
\textcolor{lime}{ずんだもん: }生徒役なのだ

\footnotesize \textcolor{pink}{四国めたん:} 皆さん、こんにちは。四国めたんです

\footnotesize \textcolor{lime}{ずんだもん:} ずんだもんなのだ。こんにちはなのだ

\footnotesize \textcolor{pink}{四国めたん:} 今回もC言語のお勉強をしていきましょう

\footnotesize \textcolor{lime}{ずんだもん:} レッツゴーなのだ

\footnotesize \textcolor{pink}{四国めたん:} 第6回の今回は 浮動小数点数の四則演算 についてお話ししますわ

\footnotesize \textcolor{lime}{ずんだもん:} 前回は 整数 だったのだ

\footnotesize \textcolor{pink}{四国めたん:} そうですわね

\footnotesize \textcolor{lime}{ずんだもん:} なにか違いがあるのか?

\footnotesize \textcolor{pink}{四国めたん:} まあそれなりにはありますわね

浮動小数点の四則演算

\footnotesize \textcolor{pink}{四国めたん:} とりあえずプログラムを書いて実行してみましょう

#include <stdio.h>

void main()
{
    float x = 1.2 + 3.4;
    printf("1.2+3.4の値は%fです。\n", x);
    x = 5.6 - 7.8;
    printf("5.6-7.8の値は%fです。\n", x);
    x = 9.1 * 2.3;
    printf("9.1*2.3の値は%fです。\n", x);
    x = 4.2 / 2.0;
    printf("4.2/2.0の値は%fです。\n", x);
}

四則演算の出力

\footnotesize \textcolor{lime}{ずんだもん:} 特に問題なく計算できているのだ

\footnotesize \textcolor{pink}{四国めたん:} そうですわね

\footnotesize \textcolor{pink}{四国めたん:} 割り算も小数点以下まで計算していますわね

\footnotesize \textcolor{lime}{ずんだもん:} 整数の割り算とは少し違うのだ

0や0.0による割り算

\footnotesize \textcolor{pink}{四国めたん:} さらに0.0による割り算を見ていきますわ

#include <stdio.h>

void main()
{
    float x = 1.0 / 0.0;
    printf("1.0/0.0の値は%fです。\n", x);
}

除算エラー

\footnotesize \textcolor{lime}{ずんだもん:} 「除算、剰余演算が 0 で行われています」というエラーが発生したのだ

\footnotesize \textcolor{pink}{四国めたん:} はい、整数、浮動小数点数のどちらでも"0"で割ることは出来ないのですわ

浮動小数点の割り算の余り

\footnotesize \textcolor{lime}{ずんだもん:} ところで浮動小数点数では整数のように割り算の余りを計算できるのか?

\footnotesize \textcolor{pink}{四国めたん:} 確認してみましょう

#include <stdio.h>

void main()
{
    float x = 8.0 % 7.0;
    printf("8.0%%7.0の値は%fです。\n", x);
}

剰余算エラー

\footnotesize \textcolor{lime}{ずんだもん:} エラーが出たのだ

\footnotesize \textcolor{pink}{四国めたん:} はい、浮動小数点数に対しては 余り の計算はできないのですわ

演算の順番

\footnotesize \textcolor{lime}{ずんだもん:} ところで演算の順番については整数と同じなのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、全く同じですわね

\footnotesize \textcolor{pink}{四国めたん:} 覚えていらっしゃいますか?

\footnotesize \textcolor{lime}{ずんだもん:} 当然なのだ

\footnotesize \textcolor{lime}{ずんだもん:} まず括弧"()"があれば、その中を先に計算するのだ

\footnotesize \textcolor{lime}{ずんだもん:} 次に掛け算と割り算を左から計算するのだ

\footnotesize \textcolor{lime}{ずんだもん:} 最後に足し算と引き算を左から計算するのだ

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{pink}{四国めたん:} とりあえずプログラムを書いて実行してみましょう

#include <stdio.h>

void main()
{
    float x = 1.0 + 2.0 * 3.0;
    printf("1.0+2.0*3.0の値は%fです。\n", x);
    x = (1.0 + 2.0) * 3.0;
    printf("(1.0+2.0)*3.0の値は%fです。\n", x);
}

演算の順序

\footnotesize \textcolor{pink}{四国めたん:} 最初の1.0 + 2.0 * 3.0は掛け算が先に計算されますので"7.000000"が答えとなりますわ

\footnotesize \textcolor{pink}{四国めたん:} 次の(1.0 + 2.0) * 3.0は括弧"()"内が先に計算されますので"9.000000"が答えとなりますわね

\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ

整数と浮動小数点の演算

\footnotesize \textcolor{lime}{ずんだもん:} 今までは整数どうしの演算や浮動小数点数どうしの演算をしてきたのだ

\footnotesize \textcolor{lime}{ずんだもん:} でも整数と浮動小数点数が混ざった演算はどのようになるのだ?

\footnotesize \textcolor{pink}{四国めたん:} まずはプログラムを実行して確認してみましょう

#include <stdio.h>

void main()
{
    float x = 1 + 2.3;
    printf("1+2.3の値は%fです。\n", x);
    x = 4.5 - 6;
    printf("4.5-6の値は%fです。\n", x);
    x = 8.9 * 10;
    printf("8.9*10の値は%fです。\n", x);
    x = 1.0 / 2;
    printf("1.0/2の値は%fです。\n", x);
}

整数と浮動小数点の演算

\footnotesize \textcolor{pink}{四国めたん:} 特に問題はないようですわね

\footnotesize \textcolor{lime}{ずんだもん:} 浮動小数点数の四則演算と変わりがないのだ

\footnotesize \textcolor{pink}{四国めたん:} はい、実はC言語では整数と浮動小数点数の両方を含む演算の場合は自動的に整数が浮動小数点数に変換されてから計算されますわ

\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ

整数への変換

\footnotesize \textcolor{pink}{四国めたん:} ちなみに int型 の変数に浮動小数点数を含む計算を代入すると小数点以下が切り捨てられて整数に変換されますわ

\footnotesize \textcolor{lime}{ずんだもん:} え~、そうなのか?

\footnotesize \textcolor{pink}{四国めたん:} 確認してみましょう

#include <stdio.h>

void main()
{
    int x = 1 + 2.3;
    printf("1+2.3の値は%fです。\n", x);
    x = 4.5 - 6;
    printf("4.5-6の値は%fです。\n", x);
    x = 8.9 * 10;
    printf("8.9*10の値は%fです。\n", x);
    x = 1.0 / 2;
    printf("1.0/2の値は%fです。\n", x);
}

整数と浮動小数点の演算

\footnotesize \textcolor{lime}{ずんだもん:} あれぇ?答えが全て"0.000000"になっているのだ

\footnotesize \textcolor{pink}{四国めたん:} ごめんなさい、printfで"x"を表示する部分が"%f"と浮動小数点数を表示する 書式指定子 になっていますわね

\footnotesize \textcolor{pink}{四国めたん:} 正しくは"%d"ですわ

\footnotesize \textcolor{pink}{四国めたん:} 修正して実行してみましょう

#include <stdio.h>

void main()
{
    int x = 1 + 2.3;
    printf("1+2.3の値は%dです。\n", x);
    x = 4.5 - 6;
    printf("4.5-6の値は%dです。\n", x);
    x = 8.9 * 10;
    printf("8.9*10の値は%dです。\n", x);
    x = 1.0 / 2;
    printf("1.0/2の値は%dです。\n", x);
}

整数と浮動小数点の演算

\footnotesize \textcolor{lime}{ずんだもん:} お~、今度はしっかりと整数で表示できたのだ

誤差

\footnotesize \textcolor{pink}{四国めたん:} 今まで見てきた浮動小数点数の演算は基本的には正確な答えが得られていましたわね

\footnotesize \textcolor{lime}{ずんだもん:} 当然ではないのか?

\footnotesize \textcolor{pink}{四国めたん:} いいえ、一般的にC言語における浮動小数点数の演算については概ね不正確ですわね

\footnotesize \textcolor{pink}{四国めたん:} 理由は色々とあるのですが、演算結果は正確な計算値よりも 誤差 と呼ばれるズレが生じますわ

\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?

\footnotesize \textcolor{pink}{四国めたん:} 実際に試してみましょう

#include <stdio.h>

void main()
{
    float x = 77777.7 + 1.23456;
    printf("77777.7+1.23456の値は%fです。\n", x);
    x = 123.456 * 1.2;
    printf("123.456*1.2の値は%fです。\n", x);
}

誤差

\footnotesize \textcolor{lime}{ずんだもん:} う~ん、何がダメなのだ?

\footnotesize \textcolor{pink}{四国めたん:} 本来、演算が正確であれば結果は"77778.934560"と"148.147200"になるはずですわ

\footnotesize \textcolor{pink}{四国めたん:} でも、実際には"77778.937500"と"148.147202"と微妙にズレていますわね

\footnotesize \textcolor{lime}{ずんだもん:} 本当なのだ

\footnotesize \textcolor{pink}{四国めたん:} 実用上は問題にならない場合も多いですわね

\footnotesize \textcolor{pink}{四国めたん:} でも演算を繰り返す場合などは誤差が大きくなって問題になる場合も出てきますわ

\footnotesize \textcolor{lime}{ずんだもん:} 何とかならないのか?

\footnotesize \textcolor{pink}{四国めたん:} 解決方法は色々とあるのですが、一番簡単なのは変数を float型 から double型 に変更することですわ

\footnotesize \textcolor{pink}{四国めたん:} double型float型 と同じ浮動小数点数を表す型ですが、圧倒的に正確な計算が可能な型と考えてよろしいですわ

\footnotesize \textcolor{lime}{ずんだもん:} お~、なんかすごいのだ

\footnotesize \textcolor{pink}{四国めたん:} とりあえずfloatdoubleに変更して試してみましょう

#include <stdio.h>

void main()
{
    double x = 77777.7 + 1.23456;
    printf("77777.7+1.23456の値は%fです。\n", x);
    x = 123.456 * 1.2;
    printf("123.456*1.2の値は%fです。\n", x);
}

誤差修正

\footnotesize \textcolor{lime}{ずんだもん:} 今度は正確な結果が表示されているのだ

\footnotesize \textcolor{pink}{四国めたん:} とはいえ double型 でも完全に正確ではなく、やはり微妙なズレが出てきますわ

\footnotesize \textcolor{pink}{四国めたん:} でも実用上は問題ないでしょう

\footnotesize \textcolor{pink}{四国めたん:} また、最近のパソコンやタブレットなどは float型 よりも double型 の方が扱い易く作られていますわ

\footnotesize \textcolor{pink}{四国めたん:} ですので、浮動小数点数を扱う場合には基本的に double型 を使用する方が良いかもしれませんわね

\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ

浮動小数点数の演算と誤差

まとめ

\footnotesize \textcolor{pink}{四国めたん:} お疲れさまでした

\footnotesize \textcolor{pink}{四国めたん:} 以上で 浮動小数点数の四則演算 を終了しますわ

\footnotesize \textcolor{lime}{ずんだもん:} おつかれさまなのだ

\footnotesize \textcolor{pink}{四国めたん:} 浮動小数点数の四則演算も小学校の算数レベルのお話なので、演算子さえ押さえておけば問題ないはずですわ

Discussion