0

私は自分のプログラムを実行しようとしています、そして私は使用しています

double result = cos(90*M_PI/180);
NSLog("Cos 90 value %g",result);  //Prints 6.12323e-17

しかし、私がこれを実行すると

 NSLog("Cos 90 value %f",cos(90*M_PI/180)); //Prints 0

結果(double)でcos90の値を取得したいのですが、これは0である必要があります。浮動小数点の空気熱問題を知っていますが、それを解決する方法はありますか?

ありがとう

4

3 に答える 3

1

の引数cosはラジアンであるため、90度の正弦を計算するには、π/2ラジアンを渡します。π/2は約1.570796326794896619です。π/2に最も近いIEEE754ダブルは約1.570796326794896558です。明らかに、これらは異なります。後者の正弦は約6.123• 10-17です。したがって、コサインルーチンは正しく機能しています。渡された数値のコサインを返します。

cosπ/2はdoubleとして表現できないため、π/2をに渡すことはできません。

要件によっては、回避策がある場合があります。たとえば、この式は(おおよそ)xの正弦(度単位)を返し、xが90の場合は正確にゼロになりますsin(M_PI/180*(90-x))

于 2012-11-16T02:19:05.590 に答える
0

問題は、結果が小さすぎることです。唯一の違いはフォーマット指定子です。%g%fは異なります。%f通常、小数点以下6ポイントの精度がありますが、%g科学的記数法を使用して小さい数値を表します。を使用して、小数点以下に印刷される文字数を拡張できます%.100f。ここで、100は小数点以下の文字数です。ただし、これはあまり正確ではなく、小数点以下の桁数が多い場合は精度が保証されません。

編集:まあ、今私はあなたが実際に計算しようとしていることに気づきました。そのレベルでの浮動小数点演算は丸めなどのために不正確であるため、ゼロではありません。

于 2012-11-15T18:03:25.117 に答える
0

最後に私は解決策を見つけました。すべての説明は正しいですが、この問題の「一時的な」解決策はNSNumberFormatter.

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];

[formatter setAlwaysShowsDecimalSeparator:NO];
[formatter setAllowsFloats:YES];
[formatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[formatter setMinimumFractionDigits:0];
[formatter setMaximumFractionDigits:10]; //THIS IS IMPORTANT AS AFTER DECIMAL, DIGITS SHOULD BE LESS THAN 17 because there is difference of 6.12323e-17 

double result = cos(90*M_PI/180);
NSNumber *numberResult = [NSNumber numberWithDouble:result];

[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSLog(@"%@",[formatter stringFromNumber:number]); //Prints 0

これは一時的な解決策です。%fを使用してcos 90の値を出力することもできますが、小数点以下の不要な60も出力されます。

于 2012-11-19T17:55:08.343 に答える