2013-09-05 21 views
13

誰もが以下の値が0に等しくない理由を知っていますか?pythonとnumpyを使用するとsin(180)がゼロにならないのはなぜですか?

import numpy as np 
np.sin(np.radians(180)) 

か:

np.sin(np.pi) 

私のpythonにそれを入力すると、それは私に1.22E-16を与えます。

+7

浮動小数点の丸め誤差です。 – Keith

+3

Piは浮動小数点数として正確に表現できないので、 'sin(pi)'は正確にゼロになることはありません。 – Blender

+0

修正プログラムがありますか、それをintに変換する必要がありますか? – MCF

答えて

13

数字πは、浮動小数点数として正確に表現することはできません。だから、np.radians(180)πを与えていない、それは3.1415926535897931を与える。

sin(3.1415926535897931)は実際には1.22e-16のようなものです。

だから、どうやってこれに対処しますか?

あなたが書く、うまく、あるいは少なくとも推測、適切な絶対および/または相対誤差の限界、そして、代わりにx == yのする必要があります。

abs(y - x) < abs_bounds and abs(y-x) < rel_bounds * y 

(これはまた、あなたが整理しなければならないことを意味あなたの計算の相対誤差はxによりyに大きな相対的であるように。あなたのケースでは、yが一定0あるので、それは些細な、ちょうど後方にそれを行うのです。)

numpyのは全体のあなたのためにこれを行う機能を提供配列全体、allclose

np.allclose(x, y, rel_bounds, abs_bounds) 

(これは実際にabs(y - x) < abs_ bounds + rel_bounds * y)をチェックし、それはほとんど常に十分だし、それがないときは、簡単にコードを再編成することができます。)お使いの場合には

np.allclose(0, np.sin(np.radians(180)), rel_bounds, abs_bounds) 

ので、どのように正しい範囲が分かっていますか?あなたはSOの答えで十分なエラー分析を教える方法はありません。 WikipediaのPropagation of uncertaintyに概要が掲載されています。本当に手掛かりがない場合は、デフォルト値の1e-51e-8の絶対値を使用できます。

+2

私は実際にエラー分析の知識があるので、これは非常に役に立ちます。 – MCF

+2

この特定の場所でのエラーは、np.radians(180)でのエラーとほぼ正確に等しくなります。その誤差はおそらく約0.5〜1.0 ULP(最後の場所の単位)、または約3.14 * DBL_EPSILON、または約7e-16です。私の誤差見積もりは最悪の場合の見積もりであったため、実際の誤差は少し小さくなりました。 詳細については、この記事を参照してください(そしてこの結果がいかにすばらしく素晴らしいかについてのいくつかの考え方)。 https://randomascii.wordpress.com/2014/10/09/intel-witherestimates-error-bounds-by- 1-3-quintillion/ –

-3

問題はpiの丸め誤差ではありません。問題は余弦のために表示されないことを 注:

In [2]: np.sin(np.pi) 
    Out[2]: 1.2246467991473532e-16 != 0. 
    In [3]: np.cos(np.pi) 
    Out[3]: -1.0     == -1. 

問題は、多くの...複雑です。これは、プロセッサ内部のpiの精度に関連しています。これはここで発見され、説明されました: https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/

+1

その記事(私の記事、それが判明したように)は、Piの丸め誤差がこの問題の大きな部分であることを説明しています。 sin(double(pi))がゼロを返すと、sin関数が壊れます。この記事で指摘しているバグは、いくつかのマシンでsin(double(pi))が*間違った*非ゼロの数値を返すということです。 Cosは、計算誤差(cos(π)の勾配がゼロ、sin(π)の勾配が1)および解の大きさに関連する1.0の精度のしきい値を下回っているために機能します。 –

関連する問題