6

宿題をしていると、理由がわからないという本当に奇妙なことに気づきました。

int x = 5;
cout << pow(x, 2);

結果は25です。それで問題ありません。しかし、私がこのように同じプログラムを書く場合:

int x = 5;
int y = pow(x, 2);
cout << y;

結果は24です!

xが2、3、4、6、7、8の場合は問題ありませんが、5、10、11、13などの場合、結果は本来より1低くなります。

if()でも同じです。

for (int x = 1; x <= 20 ; x++) {
    if (x * x == pow(x, 2)) 
    cout << x << endl;
}

数字の1、2、3、4、6、8、12、16を出力します。

4

4 に答える 4

10

std::pow()浮動小数点数を返します。たとえば、結果がに24.99999999キャストされた場合int、にカットオフされ 24ます。

これが、2番目のコード例で行うことです。
cout最初のコード例では、に変換せずint、正しい結果を出力します。

于 2013-02-05T18:16:32.090 に答える
6

'pow'は、intではなくdouble値を返します。double値は、intとしてキャストされると切り捨てられます。

http://www.cplusplus.com/reference/cmath/pow/

doubleとintを比較することはお勧めしません。

http://www.cplusplus.com/reference/cmath/pow/

コードを機能させるためのマイナーな編集:

int x = 5;
double y = pow(x,2);   // correct datatype
cout << y;
于 2013-02-05T18:16:25.477 に答える
5

pow関数は、整数ではなく、floatとで機能します。doubleこれを整数に割り当てると、浮動小数点データの表現に精度の問題があるため、値が切り捨てられる場合があります。

すべてのコンピューター科学者が浮動小数点演算について知っておくべきことを読むことをお勧めします。これは、この動作が見られる理由を説明しているためです。

そうは言っても、doubleの代わりに値を使用するとint、期待する結果が得られる可能性があります。

于 2013-02-05T18:16:57.210 に答える
0

pow()関数は通常、数学ライブラリに実装され、場合によってはターゲットプロセッサで特別な命令を使用し ます。x86の場合は、「方法:x86のpow(real、real)」を参照してください。ただし、やなどの命令fyl2xf2xm1高速ではないため、全体で100CPUサイクルかかる可能性があります。パフォーマンス上の理由から、gccのようなコンパイラーは、特別な場合に計算をより高速に実行するための強度低下を提供する「組み込み」関数を提供します。累乗Nが整数(あなたの場合のように)で小さく(あなたの場合のように)である場合N、ライブラリ関数を呼び出すよりも時間を乗算する方が高速です。

累乗が整数である場合を検出するために、数学ライブラリは、たとえば、オーバーロードされた関数を提供しますdouble pow(double,int)。gccが変換することがわかります

double x = std::pow(y,4);

内部的に2つの乗算になります。これは、ライブラリ呼び出しよりもはるかに高速で、両方のオペランドが整数の場合に期待する正確な整数の結果を提供します。

double tmp = y * y;
double x = tmp * tmp;

このタイプの強度低下を取得するには、

  1. <cmath>を含める

  2. 最適化-O2でコンパイル
  3. ライブラリ内のpow関数を明示的に呼び出して、std::pow()それがmath.hからのバージョンではなく、取得したバージョンであることを確認します。

次に、次のように見える<cmath>のオーバーロードされたpow関数を照合します。

inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); }

__builtin_powiこの関数は、累乗が小さい整数の場合に、pow()の乗算への強度低下を認識して実装されていることに注意してください。

于 2013-02-05T19:05:12.610 に答える