比较浮动列表

lal*_*lli 3 ocaml

我写了一个代码:

let rec compareVs v1 v2 =
 if List.length v1 == 0 then
  true
 else
  ((match v1 with [] -> 0. | h::l -> h) == (match v2 with [] -> 0. | h::l -> h)) && 
  (compareVs(match v1 with [] -> [] | h::l -> l) (match v2 with [] -> [] | h::l -> l))
Run Code Online (Sandbox Code Playgroud)

并运行它:

# compareVs [0.1;0.1] [0.1;0.1];;
- : bool = false
Run Code Online (Sandbox Code Playgroud)

似乎无法找到问题.请帮忙.

编辑

问题与浮点数比较接缝:

# 0.1 == 0.1;;
- : bool = false
# 1.0 == 1.0;;
- : bool = false
Run Code Online (Sandbox Code Playgroud)

我们怎样才能比较ocaml中的浮点数?

sep*_*p2k 11

使用=,而不是==.

浮点数是ocaml中的引用类型,用于==检查引用相等性.所以0.1 == 0.1是错误的.

通常,您几乎总是想要使用=,而不是==比较两个值.

请注意,除此之外,您的函数将返回true两个不同大小的列表.假设这不是你想要的,你应该只在两个列表都为空时返回true,而当其中一个列表为空而另一个列表为空时返回false.

作为样式注释,List.length用于检查列表是否为空通常是一个坏主意(一方面它是O(n),即使它可以在O(1)中进行模式匹配).在开头使用模式匹配也会清理你的代码.

像这样:

let rec compareVs v1 v2 = match v1, v2 with
| [], []       -> true
| [], _
| _, []        -> false
| x::xs, y::ys -> x = y && compareVs xs ys
Run Code Online (Sandbox Code Playgroud)

哦,如果这不仅仅是一个练习,请注意你可以做,v1 = v2而不是真的需要为此编写一个函数.

  • @lalli:`v1,v2`是一个元组,你可以像对任何其他对象一样在元组上进行模式匹配.有关模式匹配的信息,另请参见[本页](http://caml.inria.fr/pub/docs/oreilly-book/html/book-ora016.html#toc14). (3认同)

nlu*_*oni 5

Sepp2k是正确的,但作为关于比较浮点数(通常是危险的)的额外讨论,以下函数对我有所帮助:

这比较了两个具有容差的浮点数,epsilon语法与其他浮点函数类似.明显延伸>.,其他显而易见.

let epsilon = 1.0e-10
let (=.) a b = (abs_float (a-.b)) < epsilon
Run Code Online (Sandbox Code Playgroud)

如果要处理浮点数的许多极值,则应该查看pervasives模块中的classify_float函数.我不记得NAN=功能中如何比较值的问题.如果需要,您可以独立试验.

我已经使用了一段时间,但它的容差实际上是我的使用率低(epsilon如上所述,非常小的值).这没有考虑到NAN-NAN的作用.所以,这可能没用.

    let (=.) a b = match classify_float ( a -. b ) with
        | FP_infinite  | FP_nan | FP_normal -> false
        | FP_subnormal | FP_zero -> true
Run Code Online (Sandbox Code Playgroud)