2013-02-24 2 views
1

Я изо всех сил пытаюсь понять причину этой проблемы. К точке:система зависает при разложении поплавка вместо целого числа

1), проходящей целое число (10) к следующей функции факторизационной работает сразу:

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

factorize(0) -> 1; 
factorize(N) -> N * factorize(N-1). 

2) Передача с плавающей точкой (10,0) вызовет процесс пучка повесить, принимая высокий процессор и даже не заканчивается. Обратите внимание, что это небольшое значение. Я могу факторизовать высокое целое число и получить почти немедленный ответ, но небольшое число с плавающей запятой 10.0 приведет к зависанию.

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

factorize(0) -> 1; 
factorize(N) -> N * factorize(N-1). 

Вопрос: почему на Земле Эрл бы это повешение происходит с некоторым простым умножением возвратности поплавков?

+0

Операции с плавающей запятой неточны. Скорее всего, вы никогда не попадаете в базовый случай со строгим равенством нулю. (Таким образом, ваш процессор масштабируется в негативах так быстро, как может). – Mat

+0

вы прибивали его. Благодарю. PLS не стесняйтесь добавить ответ. Я добавил условие case, например case (N> = 1), и возвратил 1 в случае false, поэтому, вероятно, совпадение на factorize (0) не сработало для factorize (0.0) – gextra

ответ

3

As documentation says, есть две операции для сравнения равенства членов в Erlang, и они отличаются только в обращении с целым и поплавки:

  • =:= - точно равны - которая подсчитывает число равны, если типы совпадают, и их значения совпадают слишком false = (0.0 =:= 0)
  • == - равный - подсчитывает число равны, если их значения совпадают, но их типы не могут быть равны true = (0.0 == 0)

Сравнение шаблонов использует первый - точно равный - оператор, поэтому ваша функция зависает во втором предложении.

Другая проблема с поплавками - это приблизительное значение. Вы никогда не можете быть уверены, что у вас есть точное значение, особенно после арифметической операции. Существует обычная практика использования малого значения epsilon в тестах равенства поплавков.

is_zero(F) -> (F < 1.0e-10) andalso (F > -1.0e-10). 
+0

. это действительно хорошая информация для моего обучения erlang. – gextra

Смежные вопросы