ページ 1 / 1
宣言の型について
Posted: 2008年8月03日(日) 20:54
by array
他スレを見てたら、気になったので質問させてもらいます。
私は、情報系じゃないけど授業で半年ほど上っ面だけ習いました。
その時、int型は整数、double型は少数だ!
int a=1.0;
or
a = 1/2;
double b=1;
b = 2/1;
なんてしたら絶対だめだぞ!
int a=1;○
a = 2/1;ok
double b=1.0;○
b = 2.0/1.0;○
動くけどたまたま動作してるだけだ!、予想しない不具合につながるぞ!といわれたのですが
要するに、型たいして対応してない書き方をしちゃダメだよ。って事なんだと思いますが
そう言ってたので、実際もそうなんでしょうが・・・・
龍神録の館では、スピードや角度計算に、普通に整数使っていたので・・・。
最近ではdoubleでも気にしないで、1とか整数を書いていますが、やはりこれからは意識して1.0と書いた方がいいのかと思い質問しましたm(_ _)m
Re:宣言の型について
Posted: 2008年8月03日(日) 21:00
by array
ちょっと他にも気になる間違い例を上げておきます
//宣言部
int a,b;
double c,d;
/-中略何があったとしても-/
a = 60*c;
a = 60+c;
b = a+c;
d = a+c;
他にも間違いを作る組み合わせはあると思うのですが、『いや、その書き方あってるよ』ってのはありますか?
Re:宣言の型について
Posted: 2008年8月03日(日) 21:17
by box
> その時、int型は整数、double型は少数だ!
少数ではなくて小数です。
> int a=1.0;
問題ありません。コンパイル時に警告が出るかもしれませんけれど。
> a = 1/2;
問題ありません。aにはゼロが入ります。意図と同じかどうかは別として。
> double b=1;
問題ありません。bには1.0が入ります。
> b = 2/1;
問題ありません。bには2.0が入ります。
> なんてしたら絶対だめだぞ!
というわけで、絶対ダメだというわけではありません。
速度が気になるのであれば、例えば上記の
b = 2 / 1;
と、
b = 2.0 / 1.0;
とを、それぞれ1億回くらい繰り返すようなループを作って、
各々の実行時間がどれくらい違うのかを確認してみればよいと思います。
Re:宣言の型について
Posted: 2008年8月03日(日) 21:20
by box
> //宣言部
> int a,b;
> double c,d;
>
> /-中略何があったとしても-/
>
> a = 60*c;
右辺を計算するときに整数の60をdoubleに格上げして、double型で計算します。
その結果をint型のaに代入するときに、小数点以下を切り捨てるだけです。
そういう仕組みをわかった上で書いているのであれば、間違いではありません。
他の例も同様です。
Re:宣言の型について
Posted: 2008年8月03日(日) 21:27
by たかぎ
> とを、それぞれ1億回くらい繰り返すようなループを作って、
> 各々の実行時間がどれくらい違うのかを確認してみればよいと思います。
インタープリタのような処理系を除けば、定数式になるので何回繰り返しても同じです。
また、インタープリタの場合でも、少なくともCINTではバイトコードにコンパイルするのでやはり何回繰り返しても同じです。
ただし、状況によっては、バイトコードにならないことがあるので、その場合には影響が出るでしょう。
いずれにせよ、予測しない不具合につながることはありません。
Re:宣言の型について
Posted: 2008年8月03日(日) 21:35
by array
参考書なんかにdouble型に対してなんかに1が使われてたりすると、これ間違いだよ1.0ね。と言ってたので。
ちょっと過剰に書いてしまいましたが、問題ないのであれば良かったです。
速度というのは処理速度ではなく、整数を使ってるよという事だけの話でした><
今日、弾幕計算やってた時に以下の様な現象があったで・・・自分が理解していない上で書いてたのでboxさんとたかぎさんの回答をもとに考察してみます。
#include <stdio.h>
int main(void)
{
int n;
double i;
printf("%f\n", i);
for(n=0; n<10000; n++)
i += 1/6;
printf("%f\n",i);
return 0;
}
##実行結果
0.000000
0.000000
テスト2
#include <stdio.h>
int main(void)
{
int n;
double i;
printf("%f\n", i);
for(n=0; n<10000; n++)
i += 1.0/6.0;
printf("%f\n",i);
return 0;
}
##実行結果
0.000000
1666.666667
Re:宣言の型について
Posted: 2008年8月03日(日) 21:39
by array
> 右辺を計算するときに整数の60をdoubleに格上げして、double型で計算します。
> その結果をint型のaに代入するときに、小数点以下を切り捨てるだけです。
> そういう仕組みをわかった上で書いているのであれば、間違いではありません。
> 他の例も同様です。
>
1/6だからintで計算して切り捨てて0になったのをdoubleに入れるから予想しない結果になったんですね><;
勉強になりました。
Re:宣言の型について
Posted: 2008年8月03日(日) 21:56
by array
とりあえず、1.0/6や1/6.0、1/2や9/10を試してみました所、計算部にdoubleがあると他はintは格上げされ、int型のみだと切り捨てされる事が分りました^^
これからちゃんとした使い分けができそうです。
それとバイトコードというのが分からなかったので調べてみましたが、簡単にはわかりそうになかったので諦めました。
皆さん回答ありがとうございます^^
Re:宣言の型について
Posted: 2008年8月03日(日) 22:04
by 管理人
>>その時、int型は整数、double型は少数だ!
>少数ではなくて小数です。
もっと突っ込むと実数ですね(小数が扱えるという表現が適切でしょうか)
余談ですが、
1.0f
と書くとfloatを意味します。
1.0
と書くとdoubleを意味します。
だから
float a;
a= 2/3.0f;
では警告は出ませんが、
a=2/3.0;
だと警告が出ると思います。
int型とdouble型を計算するとdoubleになり、
floatとdoubleを計算するとdoubleになり、
intにdoubleを代入すると整数になる、
とかさえ覚えておけば、計算の過程で何の値がどうなっているのか確認できると思います。
Re:宣言の型について
Posted: 2008年8月03日(日) 22:06
by box
> double i;
>
> printf("%f\n", i);
0.000000
と出力したのは「偶然」です。定義しただけで初期化していない
変数の値は、不定です。
Re:宣言の型について
Posted: 2008年8月03日(日) 22:12
by array
たしかに警告を出していました。似た経験で以前に
int i;
i++;
とした時にエラー起こしてました。最初から0が入ってるわけではないんですね。
Re:宣言の型について
Posted: 2008年8月03日(日) 22:22
by 管理人
逆にグローバル変数だったら最初から0がはいっています。
Re:宣言の型について
Posted: 2008年8月03日(日) 23:15
by array
他にもif()内での計算やら・・・色々やってみて大体どんな値になるか分りました。
参考書なんかには書いてない事が聞けて勉強になりました^^
Re:宣言の型について
Posted: 2008年8月03日(日) 23:56
by たかぎ
> もっと突っ込むと実数ですね(小数が扱えるという表現が適切でしょうか)
いや、実数というのは「虚数」に対しての「実数」です。
実際、Cの規格にも「実数型」というのが出てきて、それは、整数型と実浮動小数点型の総称ということになっています。
虚数型というのは、double _Complexとかdouble _Imaginaryとかのことで、doubleなどの実浮動小数点型と虚数型をあわせたものが「浮動小数点型」です。
Re:宣言の型について
Posted: 2008年8月04日(月) 00:43
by 管理人
確かに実数は整数を含むので、
整数か実数かという言い分けは適切ではないですね。