パソコン活用研究シリコンバレー(C、C++、の活用研究)

キャスト演算子とオートキャスト
(準備中)

Cの割り算

整数型と実数型が混在する計算の場合、結果がどうなるか(整数型になるのかか実数型になるのか)、
また、小数点以下はどう扱われるかについて注意が必要です。

C言語のデータ型や演算子の基本的事項については以下の関連するページをご参照下さい。
Cのデータ型の基本
Cの演算子

また、BaiscやVBAにおけるオートキャストについては、兄弟サイトの整数型へのオートキャスト
VB.netにおけるオートキャストについては、兄弟サイトのVB.netの整数型へのオートキャスト
をご参照ください。


下記の実例では、実数型変数のa、整数型変数のb にともに99.5(実数)を読み込んでいる。
a,bをprintfで出力すると、
a=99.500000
b=99
と出力される。
整数型変数bに代入された99.5は自動的に小数点以下は切り捨てされ、99に丸められている。
Cでは、実数を整数型変数に代入すると小数点以下は自動的に切り捨てられて整数に変換される。
これがオートキャスト(自動型変換)と呼ばれるもの。

次にともに整数型変数であるn1,n2に
n1=99.500000/10
n2=99/10
という計算をして、結果の値を出力している。結果は
n1=9
n2=9
これも、整数型変数n1,n2に代入される時にオートキャストされた結果

その次は実数型変数f1,f2に
f1=99.500000/10
f2=99/10
という計算をして、結果の値を出力している。結果は
f1=9.950000
f2=9.000000
f2は整数同士の演算の結果、99/10の結果は9となるが(上記n2の結果と同じ)、実数型のf2に
代入するときに、9が実数型に自動変換(オートキャスト)されて、9.000000に変換されている。


div.c

#include <stdio.h>
int main(void){
float a,f1,f2;
int b, n1,n2;
scanf("%f %d",&a,&b);
printf("a:%f b:%d\n",a,b);
n1=a/10; n2=b/10;printf("n1:%d n2:%d \n",n1,n2);
f1=a/10; f2=b/10; printf("f1:%f f2:%f",f1,f2);
return 0;
}


実行例
c:\bcc55\Bin>div
99.5 99.5
a:99.500000 b:99
n1:9 n2:9
f1:9.950000 f2:9.000000
c:\bcc55\Bin>


計算式の中に、複数のデータ型が混在した場合には、
char < int < long < float < double の順に(右側ほど上位の型)、上位の型に変換されて演算が
行われます。
Cでは暗黙のうちに型変換が行われる(オートキャスト)のですが、明示的に型変換する(キャストといいます)
こともできます。

明示的にキャスト(cast)するる時は
(データ型名)式
のように記述します。
例えば、int型にキャストするときは
(int)式
です。

以下の最初の実行例では、
入力された12.34に対し、
ff=12.34*10.0
a=12.34*10.0
b=(int)(12.34*10.0)
c=(int)12.34*10.0
の計算をしています。

ff=12.34*10.0 は、123.400002となっています。本来は123.400000となるべきですが、
コンピュータの計算精度の問題で多少の誤差が生じています。

a=12.34*10.0 は、12.34*10.0が実数演算されて(123.400000になる)、それが整数型変数aに代入される時に
整数に変換(オートキャスト)されて123になっています。

b=(int)(12.34*10.0) は、(int)(12.34*10.0)が(int)(123.400000)と演算され、次に(int)によりint型への明示的な
castがされ、結果として123となっています。

c=(int)12.34*10.0 は、演算子の優先順位としてcast演算子のほうが乗算より高いので、先に(int)12.34が
計算されて、12になり、次に12*10.0の演算が行われて、120.000000という結果が得られ、整数型に代入
するときに、小数点以下が切り捨てられ、120という結果になっています。

2番目、3番目の例の演算結果も同様です。

#include <stdio.h>

int main(void) {
int a,b,c;
float f,ff;
scanf("%f",&f);
ff=f*10.0;
a=f*10.0;
b=(int)(f*10.0);
c=(int)f*10.0;
printf("%f\n",ff);
printf("%d\n",a);
printf("%d\n",b);
printf("%d\n",c);

return 0; }




c:\bcc55\Bin>cast
12.34
123.400002
123
123
120

c:\bcc55\Bin>cast
123.456
1234.560059
1234
1234
1230

c:\bcc55\Bin>cast
1234.567
12345.669922
12345
12345
12340


算術の型変換(arithmetic conversion)
異なった数値型の算術演算または比較が行われる時は、以下のルールで型変換が行われる。
上のルールが上位にくる。
1)一方のオペランド(変数あるいは固定数値)がLong double型なら、他方もLong double型に変換する。
2)上位ルールが適用されない場合、一方のオペランドがdouble型なら、他方もdouble型に変換する
3)上位ルールが適用されない場合、一方のオペランドがfloat型なら、他方もfloat型に変換する
4)上記の1)〜3)に該当しない場合、以下の規則に従い汎整数拡張(integral promotion)を両オペランドに行う
a)一方のオペランドがunsigned long型なら、他方もunsigned lomg型に変換する
b)上位ルールが適用されない場合、一方のオペランドがlong型で、他方のオペランドがunsigned型の時に、long型がunsigned型の全ての値を表現
 できるなら、unsigned型のオペランドをlong型に変換する。
 long型がunsined型の全ての値を表現できないない場合は、両オペランドをunsined long型に変換する。
C)上位ルールが適用されない場合、一方のオペランドがlong型なら、他方もlong型に変換する
d)上位ルールが適用されない場合、一方のオペランドがunsined型なら、他方もunsined型に変換する
e)上位ルールが適用されない場合、両オペランドはint型とする


符号付き整数と符号なし整数が混在した場合の比較演算は予期せぬエラーをおこしやすものです。
Unsigned型(符号なし型)と符号付き型のテスト」をご参照下さい。


  

TopPage