算数と違うC言語の割り算
~切り捨てられたり丸め込まれたり~

■この記事の概要

C言語で割り算を行うと、整数割り算や浮動小数点演算で予期せぬ誤差が生じる場合があります。

この記事は、割り算の結果が異なる原因と、計算誤差を避けるための対策について初心者向けに解説します。


■算数や電卓と違うC言語の割り算

●整数の割り算の結果を予想して下さい

#include <stdio.h>
int main(void){
    if((1/3)*3 == 0)
        puts("0");
    else if((1/3)*3 == 1)
        puts("1");
    else
        puts("?");
}

➡実行結果

●浮動小数点の割り算の結果を予想して下さい

#include <stdio.h>
int main(void){
    if((1.0/3.0)*3.0 == 0.0)
        puts("0");
    else if((1.0/3.0)*3.0 == 1.0)
        puts("1");
    else
        puts("?");
}

1.0/3.0  = 0.33333….
0.33333… * 3 =  0.99999…
0.99999  != 1.0 (コンピュータは有限なので点々なし)
浮動小数点の丸め誤差が発生するので
”?”が表示されると思う人は以下をクリック!

➡実行結果


■整数の割り算は小数点以下切り捨てられる

#include <stdio.h>
//摂氏を華氏に変換
double  c2f(double c){
    double  f = ((9/5)*c)+32;
    return  f;
}
//華氏を摂氏に変換
double f2c(double f){    
    double  c =  (5/9)*(f-32);
    return  c;
}
int     main(void){
    printf("F華氏\t%7.2f\n",c2f(-273.15));//絶対零度
    printf("F華氏\t%7.2f\n",c2f(0));     //氷点
    printf("F華氏\t%7.2f\n",c2f(100));   //沸点
    puts("★");
    printf("C摂氏\t%7.2f\n",f2c(-459.67));//絶対零度
    printf("C摂氏\t%7.2f\n",f2c(32));    //氷点
    printf("C摂氏\t%7.2f\n",f2c(212));   //沸点
}

➡意図しない実行結果になる

./a.out
F華氏   -241.15
F華氏     32.00
F華氏    132.00
★
C摂氏     -0.00
C摂氏      0.00
C摂氏      0.00

9/5と記述すると整数同士の演算となり
小数点以下が切り捨てられ
1.8ではなくて
1になります。


■浮動小数点で割り算の計算をすると意図した結果になる

#include <stdio.h>
//摂氏を華氏に変換
double  c2f(double c){
    double  f = ((9.0/5.0)*c)+32;
    return  f;
}
//華氏を摂氏に変換
double f2c(double f){    
    double  c =  (5.0/9.0)*(f-32);
    return  c;
}
int     main(void){
    printf("F華氏\t%7.2f\n",c2f(-273.15));//絶対零度
    printf("F華氏\t%7.2f\n",c2f(0));     //氷点
    printf("F華氏\t%7.2f\n",c2f(100));   //沸点
    puts("★");
    printf("C摂氏\t%7.2f\n",f2c(-459.67));//絶対零度
    printf("C摂氏\t%7.2f\n",f2c(32));    //氷点
    printf("C摂氏\t%7.2f\n",f2c(212));   //沸点
}

9.0/5.0として浮動小数点演算を行う必要があります。

➡意図した実行結果になる

./a.out
F華氏   -459.67
F華氏     32.00
F華氏    212.00
★
C摂氏   -273.15
C摂氏      0.00
C摂氏    100.00