我在学习Jason Hickey's Introduction to Objective Caml。OCaml中的浮点值匹配的替换是什么?
它说
Matching against floating-point values is supported, but it is rarely used because of numerical issues
好了,我们无法比拟的浮点值。
那么如果我们需要呢?那么怎么做呢?
我在学习Jason Hickey's Introduction to Objective Caml。OCaml中的浮点值匹配的替换是什么?
它说
Matching against floating-point values is supported, but it is rarely used because of numerical issues
好了,我们无法比拟的浮点值。
那么如果我们需要呢?那么怎么做呢?
为了扩展以前的答案,你可以在这个例子中使用模式与花车匹配,如:
# 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
,如上面的代码所示。
你可以匹配浮点数,它只是说它很少使用。
它很少使用,因为可能会出现精确问题。如果你有两个数字,x和y:
x = 0.000000001
y = 0.0000000009
x和y是一样的吗?这得看情况。如果x和y是计算结果,则累计舍入可以解释差异,它们可能相同。
简而言之,浮点比较通常“足够接近”,因此模式匹配很少使用它们,因为完全匹配可能会排除通常所需的“足够接近”的匹配。
您可以使用帮助函数编写pattern guards以检查是否相等,或者与某个epsilon或其他条件匹配。
当您使用代数数据类型(如Some 3: int option
)时,实际需要模式匹配。这是获取包含值的基本OCaml功能。当使用像数字这样的原始值时,模式匹配只是一个方便的符号。通常的关系运算符(和if
语句)可用。这就是你通常用于浮点值的东西。正如其他人提到的,你也可以使用模式守卫,这些守卫大部分只是另一种形式的if
声明。
该问题与OCaml无关。文章中有一个完整的解释:[每个计算机科学家应该知道的有关浮点运算的知识](http://dx.doi.org/10.1145/103162.103163)。 –