0
1

【Swift】2つの値がほぼ同じであることを判定したい

Posted at

はじめに

Swiftで同じであることを知りたいのであれば、==を使えばわかります。
しかし、今回知りたいのは「ほぼ同じである」ことです。

「ある基準値より差が小さければ同じものであるとする」ということがしたいです。

どういうことかというと、

値A: 5.55550
値B: 5.55555

基準値を0.0001だとすると、上の例では値Aと値Bはほぼ同じであると言えます。

テストを書く際にこういうケースは割と発生すると思います。

実際、NimbleにもbeCloseToという機能があり、「ほぼ同じ」が再現できます。

どのように実装すれば最もスマートでしょうか?

Nimbleのコードを見てみる

値Aと値Bの差の絶対値を求めて、基準値より小さいかを見ているようです。

internal func isCloseTo(
    _ actualValue: NMBDoubleConvertible?,
    expectedValue: NMBDoubleConvertible,
    delta: Double
) -> PredicateResult {
    let errorMessage = "be close to <\(stringify(expectedValue))> (within \(stringify(delta)))"
    return PredicateResult(
        bool: actualValue != nil &&
            abs(actualValue!.doubleValue - expectedValue.doubleValue) < delta,
        message: .expectedCustomValueTo(errorMessage, actual: "<\(stringify(actualValue))>")
    )
}

Nimbleではほぼ同じの基準値をデフォルトで0.0001に設定しているようです。

public func defaultDelta<F: FloatingPoint>() -> F { 1/10000 /* 0.0001 */ }

実装

イコールのように、ニアリーイコールを定義してみました。
基準値はNimbleを参考に0.0001に設定しました。

import Foundation

infix operator ≒≒ : ComparisonPrecedence

func ≒≒(left: Double, right: Double) -> Bool {
    return abs(left - right) < 0.0001
}

使い方

abの差が0.00005の時はtrueを返します。

let a: Double = 5.55550
let b: Double = 5.55555

print(a ≒≒ b) // true

abの差が0.00015の時はfalseを返します。

let a: Double = 5.55550
let b: Double = 5.55565

print(a ≒≒ b) // false

おわり

かなり勉強になりました

参考記事

0
1
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
1