キャスト

【家老】 殿、越後屋より「山吹色」が届きました。
【殿】 ほう、いかほどじゃ。
【家老】 はっ、今回は九枚ほど…
【殿】 それは結構。今回はそちの手柄が大きい。半分取るが良い。 四枚か? 五枚か? 違うな、はて、九枚の場合は折半できぬか?
【家老】 えー、2で割りますと、4.5両になりますな。
【殿】 よんてんご? てんご? てん? なんじゃその 言い方は? おぬし、また余に分からぬことを言ってたぶらかそうとする 所存じゃな? ええい、気に入らぬ! 切り捨てじゃ!
シャキーン

intとfloatの決定的な違い

コンピュータの内部では、整数と浮動小数点数は表現形式が全く違うので、 整数どうしで計算した値は、どんな計算を繰り返しても整数のままである。 たとえば、Ruby言語の場合でさえも、整数÷整数は整数となる。 以下のプログラム int-div.rb を保存し、実行してみよう。

#!/usr/koeki/bin/ruby
# coding: euc-jp

x = 9

print "xの値は ", x, "です\n"
printf "それを2で割ると %f です\n", x/2

実行してみよう。

% chmod +x int-div.rb
% ./int-div.rb
xの値は 9です
それを2で割ると 4.000000 です

最後の printf%f として浮動小数点数での 表示を指定しているにもかかわらず、結果は4となっている。これは、整数9 を整数2で割ったものが、やはり整数で表されているからである。

C言語でも同様のプログラムを作ってみよう。 以下のプログラムを bakatono.c という名前で保存し、コンパイル&実行せよ。

#include <stdio.h>

int main()
{
    int x=9;
    printf("%d を2で割ると%fじゃな,  ほほほほほー。\n", x, x/2);
}

数値どうしの型変換

多くのプログラミング言語では、整数との計算相手に浮動小数点数が 含まれていれば、計算結果も自動的に浮動小数点数に変換される。 そのためには

  1. 計算途中に小数点を含んだ数値をいれる
  2. どれかの整数(int)を浮動小数点数に変換する

のいずれかの方法を取ると良い。2つの方法は、具体的には以下のようになる。
中味が似たプログラムを作るときのコツ

  1. 計算途中に小数点を含んだ数値をいれる

    2のかわりに2.0とすればよい
    karou.c

    #include <stdio.h>
    
    int main()
    {
        int x=9;
        printf("%d を2で割ると%fでござります。\n", x, x/2.0);
    }
    
  2. どれかの整数(int)を浮動小数点数に変換する

    変数(または数値)の直前に、(float) という 型変換指令を付ける。
    karou2.c

    #include <stdio.h>
    
    int main()
    {
        int x=9;
        printf("%d を2で割ると%fなり。\n", x, (float)x/2);
    }
    

キャスト

上記2番の例のように、ある型の値を別の型に強制的に変換するときには 変換先となる型名を括弧で括って

(型名) 値

のように書けば良い。(型名)を使って 型の変換を行なうことを キャスト という。 キャストは、変換が可能な場合だけ有効である。 文字列から数値への変換はキャストでは行なえない。 文字列→数値、は atoi, atof などを利用する。

いまのところ、「整数 <->浮動小数点数数」の変換のときに利用できる とおぼえておけば良い。なお、キャストで浮動小数点数数から整数への変換を 行なう場合、小数点以下は切り捨てられる

自動変換

数値を表す型どうしが同じ項に現れた場合、C言語は

なるべく精度の高い型に揃えてから計算

しようとする。数値を表す型を、精度の低い順に並べると、

char < int <= long < float < double

となる。この性質があるので、項の中に

int x = 9;
printf("9/2=%f\n", x/2.0);

とあった場合、

intfloatが交ざってるから xのほうもfloatにしちまえ

と判断し、計算結果がfloat型になる。同様に

int x = 9;
printf("9/2=%f\n", (float)x/2);

の場合も

(float)xは、floatで、 2intだな。交ざってるから 2のほうもfloatにしちまえ

という自動変換が働き、計算結果もfloatになる。

ところが、以下のように書くと期待とおりに行かない。

int x=9;
printf("9/2=%f\n", (float)(x/2));

この場合、括弧の中 (x/2) が両方とも int なので、先に整数の割り算をして結果を4にしてしまう。そのあとで 4をfloatにしても後の祭で、結果は4.0になってしまう。

次のプログラムを実行するとなんと表示されるか。

#include <stdio.h>

int main() {
  int x=3;
  printf("x=%d です\n", x);
  printf("x/2 と x/2 を足すと %f です\n", (float)x/2+x/2);
}

なぜ3にならないのか理由を考え、3になるように修正せよ。


目次