2016-09-20 7 views
2

私のプログラムで作成された出力は、最初は正確で、5000000以上のすべての回答で0になります。私がHeron's Areaと呼ばれる関数を使用すると、 。三角形の浮動小数点数の問題

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

float heron_area(float a, float c) { 
    float s = (a + a + c)/2.0f; 
    return (s - a)*sqrtf(s*(s - c)); 
} 


int main(void) { 
    int j = 18; 
    float i = 10; 
    for (int k = 0; k < j; k++){ 
     float g = i * 10; 
     std::cout << heron_area(g, 1) << std::endl; 
     i = g; 
} 


return 0; 
} 

浮動小数点数の使用に関する問題が発生する可能性があります。なぜ私は最終出力500000の後に出力が0になるのですか?

+1

浮動小数点の代わりにdoubleを使用 – seccpur

+1

この問題は、[解決策がwikipediaにある](https://en.wikipedia.org/wiki/Heron%27s_formula#Numerical_stability) – harold

答えて

2

疑わしい浮動小数点数の問題です。

asheron_areaに印刷すると、非常に素早く同じになり、s - aがゼロになることに気づくでしょう。

caよりもはるかに小さい場合(つまり、非常に「pointy」な三角形があり、2辺が10,000,000、3番目が1の場合はゼロが表示されます)。

タイプをdoubleに変更すると、問題が後で表示されますが、表示されなくなります。

非常に大きな差異を処理したい場合は、計算を並べ替える必要があります。

a >= bb >= c、およびブラケットが必要です

Area = 0.25 * sqrt((a+(b+c)) * (c-(a-b)) * (c+(a-b)) * (a+(b-c))) 

を与える(コメントで@haroldによってリンク)Wikipedia上の解決策があります。
はい、操作の順序について心配する必要があります。

(この溶液の分析と非常に詳細な記事hereがあります。)

0

機能heron_areaにおける変数aの値を用いて、一定である変数Cを、指数関数的に大きく、大きくなるよう1.0fますます関連性が低くなります。

により浮動小数点の限られた精度発現に:

float s = a; 

従って変数(S)と同じである

float s = (a + a)/2.0f; 

float s = (a + a + c)/2.0f; 

その後に簡素化とaは同じ値を持つので、式は

です。 10
return (s - a)*sqrtf(s*(s - c)); 

s - aを減算した結果が0.0fであり、そして何によってゼロを乗算は常にゼロであるように、常に、0.0fをもたらします。

関連する問題