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

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Aozora0630
記事: 85
登録日時: 9年前
住所: 日本
連絡を取る:

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

#1

投稿記事 by Aozora0630 » 9年前

こんにちわ。

今、作っているアクションゲームでプレイヤーなどの座標を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をキャストすると 実行中に例外が発生。

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

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 13年前
住所: 大阪府
連絡を取る:

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

#2

投稿記事 by Hiragi(GKUTH) » 9年前

恐らくint型の扱える値の大きさを超えてるんじゃないですかね。
1.23456e+789 = 123456000000...
int型は -2147483648~2147483647しか表現できなかった気がします。
だいがくせい!

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

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

#3

投稿記事 by みけCAT » 9年前

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
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

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

#4

投稿記事 by みけCAT » 9年前

Hiragi(GKUTH) さんが書きました:int型は -2147483648~2147483647しか表現できなかった気がします。
Javaでは正しいと思いますが、C言語では環境依存です。
規格では少なくとも-32767~32767が表現できることが保証されています。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

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

#5

投稿記事 by みけCAT » 9年前

ちなみに、1.23456e+789および1.23456e+7899はIEEE754フォーマットの64ビット浮動小数点数で表現できる最大値(およそ10の308乗)も超えています。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
Ketty
記事: 102
登録日時: 10年前

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

#6

投稿記事 by Ketty » 9年前

主題とは関係ない恐れがありますが、
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

Aozora0630
記事: 85
登録日時: 9年前
住所: 日本
連絡を取る:

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

#7

投稿記事 by Aozora0630 » 9年前

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の構造が分かってないんだよなぁー

たいちう
記事: 418
登録日時: 13年前

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

#8

投稿記事 by たいちう » 9年前

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

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

アバター
V30
記事: 21
登録日時: 9年前
住所: 岡山県

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

#9

投稿記事 by V30 » 9年前

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ずつ座標から引いていくという処理しかしていないのに
> 何故最大値を超えてしまうのだろうか?メモリ破壊の可能性が?

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

危ない危ない。
ちゃんとした人に質問しましょう。
ちなみに私は、ちゃんとしていない素人です。

Aozora0630
記事: 85
登録日時: 9年前
住所: 日本
連絡を取る:

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

#10

投稿記事 by Aozora0630 » 9年前

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ってとんでもない数になりますね。

閉鎖

“C言語何でも質問掲示板” へ戻る