Почему в matlab sin (pi) не является точным, но sin (pi/2) точным?

У меня проблема с вычислением matlab. Я знаю, что "pi" является плавающим числом и не является точным. Таким образом, в matlab sin(pi) не точно равен нулю. Мой вопрос в том, что если "pi" не является точным, то почему sin(pi/2) точно равно 1.

sin(pi) → не является точным beacause из pi. но sin(pi/2) точно равно 1

Я удивляюсь и запутался!

Ответы

Ответ 1

Я не знаю точно, как Matlab вычисляет sin(x) - но вы можете исследовать это, вычислив его с использованием степенного ряда, т.е.

sin x = x - (x^3)/3! + (x^5)/5! - (x^7)/7! + (x^9)/9! ...

Превращая это в некоторый код Matlab, мы представляем его:

clc
x = pi;     %  or x = pi/2
res = x;
factor = -1;
for ii=3:2:19
  res = res + factor*power(x,ii)/factorial(ii);
  factor = factor*-1;  
  fprintf ( 'iteration %2i  sin(x)=%1.16f\n', (ii-1)/2, res );
end
res

Запустив этот код для x=pi и x=pi/2, вы можете увидеть, что x=pi/2 довольно быстро сходится к правильному результату (в пределах ошибки eps) (9 итераций) - в то время как случай x=pi не сходится в то же время.

Полезно отметить, что при 9 итерациях последний фактор, который вычисляется в факториале (19). Следующий факториал, который был бы рассчитан в этой последовательности, равен 21. Это последний факториал, который может быть представлен с точностью 100% из-за двойной точности (см. help factorial).

Итак, я думаю, что происходит то, что для pi/2 математическое решение сходится на 1 с точностью до двойной точности быстрее, чем pi. На самом деле pi-случай не может полностью сходиться из-за ограничений в математике и точности, которые могут быть сохранены в результате двойной точности.

Сказав все, что sin(pi) находится в пределах eps, поэтому вы должны использовать этот факт для своих целей.

Я скопировал результаты, которые я получил ниже (R2015b):

Results for PI/2
iteration  1  sin(x)=0.9248322292886504
iteration  2  sin(x)=1.0045248555348174
iteration  3  sin(x)=0.9998431013994987
iteration  4  sin(x)=1.0000035425842861
iteration  5  sin(x)=0.9999999437410510
iteration  6  sin(x)=1.0000000006627803
iteration  7  sin(x)=0.9999999999939768
iteration  8  sin(x)=1.0000000000000437
iteration  9  sin(x)=1.0000000000000000
Final Result: 1.0000000000000000


Results for PI
iteration  1  sin(x)=-2.0261201264601763
iteration  2  sin(x)=0.5240439134171688
iteration  3  sin(x)=-0.0752206159036231
iteration  4  sin(x)=0.0069252707075051
iteration  5  sin(x)=-0.0004451602382092
iteration  6  sin(x)=0.0000211425675584
iteration  7  sin(x)=-0.0000007727858894
iteration  8  sin(x)=0.0000000224195107
iteration  9  sin(x)=-0.0000000005289183
Final Result: -0.0000000005289183

Ответ 2

Причина в том, что sin(pi)=0.0, поэтому каждая маленькая ошибка, независимо от того, насколько мала она, огромна по сравнению с 0 и, следовательно, видна.

Иными словами, для sin(pi/2)=1: если алгоритм производит ошибку меньше eps (около 2.220446e-16), вы не увидите эту ошибку, потому что 1+eps=1.

Ошибка частично является результатом неточного ввода (pi значение не является точным) и частично результат округления во время вычисления. Нужно глубоко изучить код, чтобы понять его.

Другим важным фактором является сама функция. Рассматривая распространение ошибок, рассматривая серию Тейлора для pi и pi/2, мы можем видеть:

sin(pi+dx)=sin(pi)+cos(pi)dx+o(dx^2)=-dx+o(dx^2)
sin(pi/2+dx)=sin(pi/2)+cos(pi/2)dx+o(dx^2)=1+o(dx^2)

Ясно: если dx около eps, то ошибка, связанная с неточным входом, будет около eps*eps и, следовательно, не видна по сравнению с 1.