我写了一个代码:
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
而不是真的需要为此编写一个函数.
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)