Помимо расхождений, возникающих из-за ограничений внутреннего представления, проблема также может быть вызвана потерей точности при вычислении среднего значения в арифметике с плавающей запятой.
5.86.ToString "G17"
// val it : string = "5,8600000000000003"
(Seq.average [5.8;6.6;9.4;3.5;4.0]).ToString "G17"
// val it : string = "5,8599999999999994"
Рассмотрите возможность использования более подходящих числовых данныхвведите:
Seq.average [5.8;6.6;9.4;3.5;4.0] = 5.86
// false
Seq.average [5.8M;6.6M;9.4M;3.5M;4.0M] = 5.86M
// true
Чтобы ответить на реальный вопрос, как проверить равенство Option<float>
значений: «подняв» поплавки из опций, а затем выполнив проверку на равенство.Лифт - это обычная операция для монад в функциональном программировании.
Чрезвычайно упрощенно, мы собираемся запускать тест на заказ только тогда, когда оба аргумента являются Some
-случаями.Это легко сделать путем сопоставления с образцом в случаях различного объединения.
let eps = 1e-7 // or whatever is sensible in your domain
let equalityCompareFloatOption x y =
match x, y with
| Some x', Some y' -> abs(x' - y') < eps
| _ -> x = y
// val equalityCompareFloatOption : x:float option -> y:float option -> bool
equalityCompareFloatOption
(Seq.average[5.8;6.6;9.4;3.5;4.0] |> Some) (Some 5.86)
// val it : bool = true