3

浮動小数点数のGCDを計算するために次の関数を作成しましたが、これを入力(111.6、46.5)に対して実行すると、関数内のfmod(a、b)の計算により、2回の再帰呼び出し後に間違った結果が得られ始めます。ここでエラーを見つけることができません。誰かがここで何が悪いのかを見つけることができますか?

float gcd(float a, float b){
if (a>b) {
    if(b==0){
        return a;
    }
    else {
        return gcd(b, fmod(a,b));
    }
}
else {
    if (a==0) {
        return b;
    }
    else {
        return gcd(fmod(b,a), a);
    }
}

}

4

2 に答える 2

6

浮動小数点値の表現方法により、ソーステキスト「111.6」は111.599999999999994315658113919198513031005859375に変換され、ソーステキスト「46.5」は46.5に変換されます。次に、gcd関数は7.62939453125e-06を返します。これは、2つの入力値の正しいGCDです。

最初の値は14627635/131072であることに注意してください。すべての浮動小数点数は、(特定の範囲内の)整数に2の累乗で乗算または除算されます。111.6を2進浮動小数点で正確に表すことは不可能です。111.6を正確に表すことはできないため、111.6を使用して正確な計算を行うことはできません。浮動小数点は、主に近似演算用に設計されています。正確な算術演算を行うには、細心の注意が必要です。


(整数ではなく)実数のGCDについて話すとはどういう意味ですか?

abのGCDは、 a / cb / cが整数であるような最大数cです。

于 2013-01-12T20:43:43.770 に答える
0
float gcd(float a, float b){
    printf("a=%f b=%f\n",a,b);
if (a>b) {
    if(b==0){
        return a;
    }
    else {
        return gcd(b, fmod(a,b));
    }
}
else {
    if (a==0) {
        return b;
    }
    else {
        return gcd(fmod(b,a), a);
    }
}
}
main(){
    printf("%f\ndddeellliiimmiitteerr\n",gcd(1116,465));
    printf("%f\n",gcd(111.6,46.5));
}

あなたがフロートを見ることができるように、それほど正確ではありません。
あなたはdoubleを試すことができます(しかしそれも:))または...フロートがどのように保存されたかについて読んでください

于 2013-01-12T20:41:07.493 に答える