2016-09-05 5 views
-2

C++で浮動小数点数と整数計算の限界をテストする簡単なプログラムを実行しています。私は#15と#19が返されている値が間違っていることを理解していますが、なぜ#15が間違っていますか?そして、私は#19が "inf"を返すために0で割られているとは思わないので、なぜこれをやっているのですか?不正な戻り値:C++

#include "stdafx.h" 
#include "stdlib.h" 
#include <iostream> 
#include <math.h> 

float hyp(float x, float y) { 
    return sqrtf(x*x + y*y); 
} 

#include <stdio.h> 
int main(void) { 
    float x = 3.0f, y = 4.0f, z = 5.0f; 
    for (int i = 0; i < 20; i++) { 
     float e = fabsf(hyp(x, y) - z)/z; 
     printf("%2d %e\n", i, e); 
     x *= 10.0f, y *= 10.0f, z *= 10.0f; 
     std::cout << z << std::endl; 
    } 
} 

出力は次のようになります

0 0.000000e+00 
50 
1 0.000000e+00 
500 
2 0.000000e+00 
5000 
3 0.000000e+00 
50000 
4 0.000000e+00 
500000 
5 0.000000e+00 
5e+06 
6 0.000000e+00 
5e+07 
7 0.000000e+00 
5e+08 
8 0.000000e+00 
5e+09 
9 0.000000e+00 
5e+10 
10 0.000000e+00 
5e+11 
11 0.000000e+00 
5e+12 
12 0.000000e+00 
5e+13 
13 0.000000e+00 
5e+14 
14 0.000000e+00 
5e+15 
15 1.073742e-07 
5e+16 
16 0.000000e+00 
5e+17 
17 0.000000e+00 
5e+18 
18 0.000000e+00 
5e+19 
19 inf 
5e+20 
Press any key to continue . . . 
+0

結果は、 'sqrtf'の実装によって異なります。それ以上のことは言い難いです。 float内の丸め誤差(DECIMAL_DIGの値)を格納せずに格納できる小数点以下の桁数として、x、y、zの値を完全精度で格納する必要があります。 – madmann91

+0

あなたの混乱の一部は、ゼロをゼロで除算することがinfを得る唯一の方法であると仮定することから来ます。 infは演算結果であり、その結果は大きすぎるために有限数で表現できません。 –

+0

@ madmann91 'DECIMAL_DIG'は' long double'型に適用されます。ここのすべての浮動小数点型は 'float'です。 C++の実装では、 'float'中間結果と定数に' long double'精度を使用することができますが、CとC++標準は 'float'変数の内容が' float'として表現できる値でなければならないことを示しています。 –

答えて

4

最大単精度浮動小数点数が約1.7e+38ある(Wikipediaを参照します)。 5e+19を四捨五入すると、結果は2.5e39であり、大きすぎるためinfとなります。

#15でゼロ以外の結果が得られるのは、浮動小数点が近似値であるためです。 Is floating point math broken?