在OCaml中匹配浮点值的替代是什么?

时间:2012-12-12 21:10:35

标签: functional-programming ocaml

我正在学习Jason Hickey's Introduction to Objective Caml


它说

Matching against floating-point values is supported, but it is rarely used because of numerical issues


好的,我们无法匹配浮点值。

那么如果我们需要怎么办?那怎么办?

4 个答案:

答案 0 :(得分:4)

您可以匹配浮点数,它只是说它很少使用。

很少使用它,因为可能会出现精度问题。如果您有两个数字,x和y:

 x = 0.000000001
 y = 0.0000000009

x和y是否相同?这得看情况。如果x和y是计算结果,那么累积的舍入可以解释差异,它们可能是相同的。

更粗略地说,浮点比较通常“足够接近”,因此模式匹配很少使用它们,因为精确匹配可以排除通常需要的“足够接近”匹配。

答案 1 :(得分:3)

您可以使用辅助函数编写pattern guards来检查是否相等,或者使用某些epsilon或其他标准。

答案 2 :(得分:3)

要扩展之前的答案,您可以使用与浮点数匹配的模式,如下例所示:

# let float_match_example = function
    | 0. -> "exact zero"
    | x when abs_float x < 1e-12 -> "epsilon"
    | _ -> "other";;

val float_match_example : float -> string = <fun>

# List.map float_match_example [0.; 42e-15; 3.];;

- : string list = ["exact zero"; "epsilon"; "other"]

请注意,模式匹配隐式使用相等性测试,这很少是使用浮点数时所需要的:当舍入错误累积时,两个浮点数很少完全相等。因此,您可以将guards与关键字when一起使用,如上面的代码所示。

答案 3 :(得分:3)

当您使用代数数据类型(如Some 3: int option)时,实际上需要模式匹配。这是获取包含值的基本OCaml功能。使用数字等原始值时,模式匹配只是一种方便的符号。通常的关系运算符(和if语句)可用。这就是你通常用于浮点值的东西。正如其他人提到的那样,你也可以使用模式保护,它们大多只是if语句的另一种形式。