Erlang 当分解浮点而不是整数时,系统挂起

Erlang 当分解浮点而不是整数时,系统挂起,erlang,Erlang,我正在努力理解这个问题的原因。切中要害: 1) 将整数(10)传递给以下因式分解函数立即起作用: test() -> X = 10, F = factorize(X). factorize(0) -> 1; factorize(N) -> N * factorize(N-1). 2) 通过浮点(10.0)将导致beam进程挂起,占用高CPU,甚至不会终止注意这是一个很小的值。我可以分解一个高整数,并得到几乎立即的响应,但是一个小的浮点数10.0会导致它挂

我正在努力理解这个问题的原因。切中要害:

1) 将整数(10)传递给以下因式分解函数立即起作用:

test() ->
    X  = 10,
    F  = factorize(X).

factorize(0) -> 1;
factorize(N) -> N * factorize(N-1).
2) 通过浮点(10.0)将导致beam进程挂起,占用高CPU,甚至不会终止注意这是一个很小的值。我可以分解一个高整数,并得到几乎立即的响应,但是一个小的浮点数10.0会导致它挂起

test() ->
    X  = 10.0,          <-- NOTICE THE DOT ZERO 10.0
    F  = factorize(X).

factorize(0) -> 1;
factorize(N) -> N * factorize(N-1). 
test()->
X=10.0,1;
因式分解(N)->N*因式分解(N-1)。
问题:为什么在Erl地球上,这种挂起会发生在浮点数的乘法重复出现的情况下?

有两种操作来比较Erlang中的相等项,它们只在处理整数和浮点数方面有所不同:

  • =:=
    -完全相等-如果类型相同,则计数相等,并且它们的值也相同
    false=(0.0=:=0)
  • =
    -equal-如果数值相同,但类型可能不相等,则计数相等
    true=(0.0==0)
模式匹配使用第一个完全相等的运算符,这就是为什么函数在第二个子句中挂起的原因

浮点数的另一个问题是其近似值。你永远不能确定你有一些精确的值,尤其是在算术运算之后。在浮点相等测试中,通常使用小值
epsilon

is_zero(F) -> (F < 1.0e-10) andalso (F > -1.0e-10).
是零(F)->(F<1.0e-10)也是零(F>-1.0e-10)。

浮点数操作不精确。很有可能你永远不会在基本情况下严格等于零。(所以你的CPU正在尽可能快地缩小负片。)你搞定了。谢谢请随意添加答案。我添加了一个case条件,例如case(N>=1),如果为false,则返回1,因此factorize(0)上的匹配可能对factorize(0.0)不起作用