51

if ステートメント条件の一部として R の 2 つの数値を比較しようとしています。

(a-b) >= 0.5

この特定の例では、a = 0.58 および b = 0.08... ですが、まだ(a-b) >= 0.5偽です。私は==正確な数の比較に使用する危険性を認識しており、これは関連しているようです:

(a - b) == 0.5)は false ですが、

all.equal((a - b), 0.5)本当です。

私が考えることができる唯一の解決策は、2 つの条件を持つことです(a-b) > 0.5 | all.equal((a-b), 0.5)。これは機能しますが、それが本当に唯一の解決策ですか? =比較演算子のファミリを永遠に捨てるべきですか?

わかりやすくするために編集します。これは浮動小数点の問題であることはわかっています。より基本的に、私が求めているのは、それについて何をすべきかということです。>=本当に信頼できないので、Rでより大きいまたは等しい比較を処理する賢明な方法は何ですか?

4

7 に答える 7

47

私はall.equalそのようなもののファンではありませんでした。私には、寛容が不思議な形で機能しているように思えます。0.05 未満の許容誤差よりも大きいものをチェックしてみませんか

tol = 1e-5

(a-b) >= (0.05-tol)

一般に、丸めを行わず、従来のロジックのみを使用すると、単純なロジックは all.equal よりも優れていることがわかります。

もしそうx == yならx-y == 0。おそらくx-y正確に 0 ではないので、そのような場合に使用します

abs(x-y) <= tol

とにかく に対して許容誤差を設定する必要がall.equalあり、これは よりもコンパクトで簡単ですall.equal

于 2010-05-05T00:25:11.697 に答える
14

このアプローチを頻繁に使用する場合は、これを別の演算子として作成するか、元の >= 関数を上書きすることができます (おそらく良い考えではありません)。

# using a tolerance
epsilon <- 1e-10 # set this as a global setting
`%>=%` <- function(x, y) (x + epsilon > y)

# as a new operator with the original approach
`%>=%` <- function(x, y) (all.equal(x, y)==TRUE | (x > y))

# overwriting R's version (not advised)
`>=` <- function(x, y) (isTRUE(all.equal(x, y)) | (x > y))

> (a-b) >= 0.5
[1] TRUE
> c(1,3,5) >= 2:4
[1] FALSE FALSE  TRUE
于 2010-05-04T23:21:43.803 に答える
12

完全を期すために、特定の状況では、小数点以下の桁数を単純に丸めることができることを指摘します (これは、以前に投稿されたより良い解決策と比較すると、一種の不十分な解決策です)。

round(0.58 - 0.08, 2) == 0.5
于 2010-05-05T00:12:42.557 に答える
4

いくつかの許容レベルを選択してください:

epsilon <- 1e-10

次に使用します

(a-b+epsilon) >= 0.5
于 2010-05-05T00:25:49.543 に答える
3

しかし、とにかく許容範囲を使用している場合、ab == .5 (実際) が評価されないことを気にするのはなぜですか? とにかく公差を使用している場合は、エンドポイントを正確に気にしないと言っています。

これが本当です if( (ab) >= .5) if( (ab) < .5)

それらの 1 つは、double のすべてのペアで常に true と評価される必要があります。一方を使用するコードは、少なくとももう一方に対して no 操作を暗黙的に定義します。公差を使用して実際の .5 を最初に含めても、問題が継続的なドメインで定義されている場合、あまり達成できません。根底にある問題に連続値が含まれるほとんどの問題では、0.5 を任意に超える値は常に適切に評価されるため、それを示すポイントはほとんどありません。任意に .5 に近い値は「間違った」フロー制御に送られますが、適切な精度を使用している連続的な問題では問題になりません。

公差が意味を持つのは、タイプが if( (ab) == c) if( (ab) != c) の問題を扱っているときだけです。

ここでは、「適切な精度」は役に立ちません。その理由は、ab のビットを手動で非常に低いレベルに設定しない限り、2 番目が常に true と評価されるように準備する必要があるためです。

于 2010-05-05T21:39:33.120 に答える