0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unityの誤差許容比較Approximatelyについて

Last updated at Posted at 2025-05-11

floatの誤差許容比較関数Approximately

孫引きなんですけど、デフォルトのApproximatelyはこうなってるみたいです。

public static bool Approximately(float a, float b)
{
  return (double) Mathf.Abs(b - a) < (double) Mathf.Max(1E-06f * Mathf.Max(Mathf.Abs(a), Mathf.Abs(b)), Mathf.Epsilon * 8f);
}

代入を入れて見やすくしたのがこちら

public static bool Approximately(float a, float b)
{
    // max(a,b)* 0.000001f まで誤差を許容する。でも両方0に近いと、許容誤差がほぼ0になる
    float c1 = 1E-06f * Mathf.Max(Mathf.Abs(a), Mathf.Abs(b));

    // a b が0に近いとき用の、許容誤差の最小値(これ以上は小さくならないようにする)
    float c0 = Mathf.Epsilon * 8f;

    return (double)Mathf.Abs(b - a) < (double)Mathf.Max(c0,c1);
}

自分で定義したほうがいいかも?

理由1 比較値*0.000001f は小さすぎる?

自分で値を操作できたほうがいいかなって

理由2 もっと最適化できる?

許容誤差をaとbの大きいほうを基準に計算していますが、どちらでもいいと思います。
aとbが近い場合、厳密な値の比較が必要ですが、許容誤差もどちらを使ってもほとんど同じです。
aとbが遠い場合、許容誤差の誤差なんて気にならないくらい差があります。

許容誤差係数が0.01のとき、|a|<|b|, |a|=|b|rとして計算してみると、rが0.99から0.990099の間に、aかbどちらを基準にするかで結果が分かれる区間があります。

つまり片方の値の0.99倍の値と比較した場合と、0.990099倍の

100と99.0099を比較したときどうなるか
チェックする差は0.9901
99.0099が基準なら許容誤差は0.990099 許容誤差外にあります。
100が基準なら許容誤差は1 許容誤差内にあります。

コード例

public static bool Approximately(float a,float b)
{
    // a * 0.01f までの誤差を認める
    // a b どちらでも良い
    // 差がある場合は結局false
    // 差がない場合は同じくらいの許容誤差(適正)で判断される
    float abs_a = Mathf.Abs(a);
    int z = Convert.ToInt32(abs_a < 1);
    return Mathf.Abs(a - b) < (abs_a + z) * 0.01f;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?