代入分の左辺と右辺の型が異なる場合、右辺の型が左辺の型に変換される。もし、左辺が右辺よりも大きな型であれば問題はない。その逆の場合は問題ありで、例えば次のプログラムは、「1000」と表示せずに「-24」と表示する。
#include int main(void) { char ch; int i; i = 1000; ch = i; printf("%d\n", ch); return 0; }
takatoh@nightschool $ ./sample_4_6a -24
なぜなら、int の i を char の ch に代入する際、i の下位 8 ビットだけがコピーされるから。C ではこのような代入での型変換はエラーにならない。代入文で、大きな整数から小さな整数(char を含む)に変換されるとき、上位ビットが失われるのが基本的な規則。
また、大きな浮動小数点数から小さな浮動小数点数への変換では精度が落ちるし、浮動小数点数から整数への変換では小数部が失われる。
値が変換後の型におさまらない場合は、結果は意味のない値になってしまう。
次の2点は重要。
- int から float、float から double への変換は、値の表現を変えるだけで精度を上げるものでなないこと。
- コンパイラによって、char を符号付きとして扱うものと符号なしで扱うものがある。このため 127 よりも大きな値を代入した時の結果は処理系に依存する。これが問題になる場合は明示的に signed あるいは unsigned と宣言すべき。
次のプログラムでは、浮動小数点数を整数に代入することで小数部が失われることがわかる。
#include int main(void) { int i; float f; f = 1234.0098; i = f; printf("%f %d\n", f, i); return 0; }
takatoh@nightschool $ ./sample_4_6b 1234.009766 1234
む、浮動小数点数の精度がおかしいな。とはいえ、整数に代入することで、小数部が失われることは分かった。