ページ 11

浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月23日(木) 16:31
by Aozora0630
こんにちわ。

今、作っているアクションゲームでプレイヤーなどの座標をdoubleがたに入れて管理しているのですが、そこで、doubleからintに変換する時に、まるでメモリーリークしたような値になってしまいます。

おかしいなと思いTD32デバッガで見てみたところ、その座標を代入した変数が1.000000e+12・・とか言うわけの分からない値になってました。

eが良く分からないので、新しいプロジェクトでテストしてみると・・・。↓結果

・double = 1.5 をキャストすると int = 1
・double = 1.2345678e+9をキャストすると int 12
・double = 1.23456e+789をキャストすると int ???????(良く分からない値)
・double = 1.23456e+7899をキャストすると 実行中に例外が発生。

どなたか、原因とキャスト方法を教えてください!

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月23日(木) 19:15
by Hiragi(GKUTH)
恐らくint型の扱える値の大きさを超えてるんじゃないですかね。
1.23456e+789 = 123456000000...
int型は -2147483648~2147483647しか表現できなかった気がします。

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月23日(木) 21:28
by みけCAT
Aozora0630 さんが書きました:eが良く分からないので、新しいプロジェクトでテストしてみると・・・。↓結果

・double = 1.5 をキャストすると int = 1
・double = 1.2345678e+9をキャストすると int 12
・double = 1.23456e+789をキャストすると int ???????(良く分からない値)
・double = 1.23456e+7899をキャストすると 実行中に例外が発生。
gccでは再現できませんでした。

コード:

#include <stdio.h>

void tesuto(double value) {
	int v = (int)value;
	printf("%d\n", v);
}

int main(void) {
	tesuto(1.5);
	tesuto(1.2345678e+9);
	tesuto(1.23456e+789);
	tesuto(1.23456e+7899);
	return 0;
}
出力

コード:

1
1234567800
-2147483648
-2147483648

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月23日(木) 21:30
by みけCAT
Hiragi(GKUTH) さんが書きました:int型は -2147483648~2147483647しか表現できなかった気がします。
Javaでは正しいと思いますが、C言語では環境依存です。
規格では少なくとも-32767~32767が表現できることが保証されています。

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月23日(木) 21:34
by みけCAT
ちなみに、1.23456e+789および1.23456e+7899はIEEE754フォーマットの64ビット浮動小数点数で表現できる最大値(およそ10の308乗)も超えています。

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月23日(木) 22:57
by Ketty
主題とは関係ない恐れがありますが、
double型ということに着目して一応コメしておきます。

私の認識ではDXライブラリ(というかDirectX)は、デフォルトではdouble型の精度を落としていたと思います。
実質float並みだったかな・・・忘れました(^v^;)
そこで、環境によって値がまちまちになる、という問題があるようです。

きっちりとdoubleの精度を保つためには、D3DCREATE_FPU_PRESERVEというやつを指定する必要があるようです。

DXライブラリでは、
DxLib_Init を呼び出す前に SetUseFPUPreserveFlag( TRUE ) ;
ということをする必要があります。

↓これを参考にコメントしています。
http://hpcgi2.nifty.com/natupaji/bbs/pa ... st&no=1385

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月24日(金) 17:50
by Aozora0630
Ketty さんが書きました:主題とは関係ない恐れがありますが、
double型ということに着目して一応コメしておきます。

私の認識ではDXライブラリ(というかDirectX)は、デフォルトではdouble型の精度を落としていたと思います。
実質float並みだったかな・・・忘れました(^v^;)
そこで、環境によって値がまちまちになる、という問題があるようです。

きっちりとdoubleの精度を保つためには、D3DCREATE_FPU_PRESERVEというやつを指定する必要があるようです。

DXライブラリでは、
DxLib_Init を呼び出す前に SetUseFPUPreserveFlag( TRUE ) ;
ということをする必要があります。

↓これを参考にコメントしています。
http://hpcgi2.nifty.com/natupaji/bbs/pa ... st&no=1385
確かにDxLib使ってます・・・。でも、テストの時は使ってませんでした・・・
みけCAT さんが書きました:ちなみに、1.23456e+789および1.23456e+7899はIEEE754フォーマットの64ビット浮動小数点数で表現できる最大値(およそ10の308乗)も超えています。
・・・。つまり、最大値が越えているって事ですよね。
というか、eとは何なんでしょうか?(自分で調べてみます)

その前に、アクションゲームの演算では0.1ずつ座標から引いていくという処理しかしていないのに何故最大値を超えてしまうのだろうか?メモリ破壊の可能性が?

とりあえず、メモリ破壊などを調べてみます。

未だにdoubleの構造が分かってないんだよなぁー

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月24日(金) 21:59
by たいちう
> その前に、アクションゲームの演算では0.1ずつ座標から引いていくという処理しかしていないのに
> 何故最大値を超えてしまうのだろうか?メモリ破壊の可能性が?

正しい演算やキャストができていないのでしょう。
再現可能な最小限のコードをここに貼ってくれれば、すぐ原因はわかりそうですが、
コードなしだと、どんなミスをしているのか、回答者には予想は困難です。

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月25日(土) 15:28
by V30
1.2345678e+9 = 1.2345678 × 10の9乗
↓1.2345678の小数点を右に9桁移動する。
つまり、
1234567800
を意味する。



1.23456e+789 = 1.23456 × 10の789乗

小数点を右に789桁移動する。
つまり、
123456000…000[0の数は全部で784個]
を意味する。



ちなみにeに続く数値が-の時は、
1.2345678e-9 = 1.2345678 × 10の-9乗

1.2345678の小数点を左にに9桁移動する。
つまり、
0.0000000012345678
を意味する。
という風になります。



プログラミングの利用環境が分からないので何とも言えませんが、
いわゆる天文学的な数値、例えば1光年(約94600000000億mm)とか
使うようなアクションゲームですか?

そうでなければ、
たいちう さんが書きました:> その前に、アクションゲームの演算では0.1ずつ座標から引いていくという処理しかしていないのに
> 何故最大値を超えてしまうのだろうか?メモリ破壊の可能性が?

正しい演算やキャストができていないのでしょう。
再現可能な最小限のコードをここに貼ってくれれば、すぐ原因はわかりそうですが、
コードなしだと、どんなミスをしているのか、回答者には予想は困難です。
↑の通りだと思います。

Re: 浮動小数点の科学記法と整数のキャスト

Posted: 2015年4月26日(日) 10:05
by Aozora0630
V30 さんが書きました:1.2345678e+9 = 1.2345678 × 10の9乗
↓1.2345678の小数点を右に9桁移動する。
つまり、
1234567800
を意味する。



1.23456e+789 = 1.23456 × 10の789乗

小数点を右に789桁移動する。
つまり、
123456000…000[0の数は全部で784個]
を意味する。



ちなみにeに続く数値が-の時は、
1.2345678e-9 = 1.2345678 × 10の-9乗

1.2345678の小数点を左にに9桁移動する。
つまり、
0.0000000012345678
を意味する。
という風になります。



プログラミングの利用環境が分からないので何とも言えませんが、
いわゆる天文学的な数値、例えば1光年(約94600000000億mm)とか
使うようなアクションゲームですか?

そうでなければ、
たいちう さんが書きました:> その前に、アクションゲームの演算では0.1ずつ座標から引いていくという処理しかしていないのに
> 何故最大値を超えてしまうのだろうか?メモリ破壊の可能性が?

正しい演算やキャストができていないのでしょう。
再現可能な最小限のコードをここに貼ってくれれば、すぐ原因はわかりそうですが、
コードなしだと、どんなミスをしているのか、回答者には予想は困難です。
↑の通りだと思います。
なるほど・・・。eってそういうことだったんですね。

では、冷害が発生するのも値がおかしくなるのもそのせいだったんですね。

だから恐らく、アクションゲームのシステム内でメモリ破壊などをしてしまったのだと思います。

応えてくださった方、ありがとう御座いました。

確かに1.23456e+7899ってとんでもない数になりますね。