2016-11-29 14 views
3

Я не могу понять, почему деление на 0 дает разные результаты в следующих двух случаях. amort - это функция, которая вычисляет график постоянной амортизации. Единственное, что мы заботимся о том, что в настоящее время является последним элементом А именно 0.Matlab division by 0: Inf или -Inf

amort = @(r,M) ((1+r).^(0:M)' - (1+r).^M) ./ (1-(1+r).^M) 

A = amort(0.03, 20); 

>> A(end)==0 
ans = 
    1 

То, что выглядит странно выглядит следующим образом:

>> 1/0 
ans = 
    Inf 
>> 1/A(end) 
ans = 
    -Inf 

Однако

>> sign(A(end)) 
ans = 
    0 
>> 1/abs(A(end)) 
ans = 
    Inf 

Как это возможно и почему? Есть ли какой-то скрытый «знак»?

+1

Возможный дубликат [Почему Октава Гну имеет отрицательные нули?] (Http://stackoverflow.com/questions/2109755/why-does-gnu-octave-have-negative-zeroes) – excaza

+0

Хотя дубликаты ссылок Octave, принятый ответ касается MATLAB и формата IEEE-754. – excaza

+1

'A (end)' отрицательный ноль. 'fprintf ('% f \ n', A (end))' возвращает '-0.000000' – excaza

ответ

6

A(end) Фактически имеет установленный бит бит (то есть отрицательный ноль). Попробуйте использовать num2hex, чтобы увидеть шестигранную представление:

>> a = -0 
a = 
    0 % Note the sign isn't displayed 

>> num2hex(A(end)) 
ans = 
8000000000000000 

>> num2hex(a) 
ans = 
8000000000000000 % Same as above 

>> num2hex(0) 
ans = 
0000000000000000 % All zeroes 

>> 1/a 
ans = 
    -Inf 

Обратите внимание, что -0 отображается как 0, но на самом деле имеет свой знак бит. Следовательно, результат -Inf.

Также отметим это объяснение sign функции (курсив мой):

Для каждого элемента X, знак (X) возвращает 1, если элемент больше нуля, 0, если она равна нулю и -1 если меньше нуля.

Поскольку -0 не меньше нуля, но вместо этого равна 0, sign возвращается 0.

+0

Я вижу - это полезно. Любая догадка, почему бит знака установлен на ноль, то? Зависит ли он от точности/аппроксимации машины при выполнении вычислений, запрошенных «amort»? Могу ли я предотвратить эти ситуации? – Giuseppe

+2

@Giuseppe: в функции 'amort' в вашем примере числитель для последнего векторного элемента будет 0, но знаменатель будет' (1-1.03^20) 'или около -0.8061. Деление 0 на отрицательное число дает вам -0. Если вы заменяете термины как в числителе, так и в знаменателе (т. Е. Умножаетесь на -1 сверху и снизу), вы можете избежать этого. – gnovice