0

の丸めfloatと への変換について、非常に奇妙な事実に直面していintます。

ここに記載されているように: http://www.gnu.org/software/libc/manual/html_node/Rounding.html

最も近い表現可能な値への丸めは、デフォルトの丸めモードです。しかし、そうではないようです。

だから私はこの簡単なプログラムを作成しました:

#include <fenv.h>
#include <stdio.h>

int a;
double b;

main() {
  b=1.3; a=b; printf("%f %d\n",b,a);
  b=1.8; a=b; printf("%f %d\n",b,a);
  b=-1.3; a=b; printf("%f %d\n",b,a);
  b=-1.8; a=b; printf("%f %d\n",b,a);
  printf("%d %d %d\n",fegetround(),FE_TONEAREST,FE_TOWARDZERO);
}

プログラムは、gcc-4.7 (debian)、cygwin gcc、および Visual studio でコンパイルされました。出力は同じで、の定義のみがFE_TOWARDZERO変更されました。

プログラムの出力:

 1.300000 1
 1.800000 1
-1.300000 -1
-1.800000 -1
0 0 3072

FE_TONEARESTしたがって、テストしたすべてのコンパイラで丸めモードが (デフォルト) に設定されていることがはっきりとわかりますが、それらはすべてゼロに向かって丸められています。

なんで?

PS: はい、使用できますMath.round()が、なぜこれが起こっているのか疑問に思っています。

4

2 に答える 2

2

丸めモードは浮動小数点丸め関数に適用されるためです。int常に切り捨てられるように変換します。

于 2013-05-31T07:26:42.807 に答える
0

わかりました、なぜこれが起こっているのかという疑問が見つかりました。ここに述べられているように:

http://software.intel.com/en-us/articles/fast-floating-point-to-integer-conversions

章で

A Closer Look at Float-to-Int Conversions

浮動小数点数から 32 ビット整数へのキャストに関する問題は、数値の小数部分を切り捨て、整数の結果を保持することによって変換を行う必要があると述べている ANSI C 標準に起因します。このため、Microsoft Visual C++ 6.0 コンパイラは (int) または (long) キャストを検出すると、_ftol C ランタイム関数への呼び出しを挿入します。この関数は、浮動小数点の丸めモードを「切り捨て」に変更し、変換を実行してから、丸めモードをキャスト前の元の状態にリセットします。

于 2013-05-31T08:06:23.130 に答える