2012-12-12 26 views
1

我在学习Jason Hickey's Introduction to Objective CamlOCaml中的浮点值匹配的替换是什么?


它说

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


好了,我们无法比拟的浮点值。

那么如果我们需要呢?那么怎么做呢?

+5

该问题与OCaml无关。文章中有一个完整的解释:[每个计算机科学家应该知道的有关浮点运算的知识](http://dx.doi.org/10.1145/103162.103163)。 –

回答

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,如上面的代码所示。

4

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

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

x = 0.000000001 
y = 0.0000000009 

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

简而言之,浮点比较通常“足够接近”,因此模式匹配很少使用它们,因为完全匹配可能会排除通常所需的“足够接近”的匹配。

3

您可以使用帮助函数编写pattern guards以检查是否相等,或者与某个epsilon或其他条件匹配。

3

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