Проблема
Вопрос заключается в том, что ваша переменная FAT1 становится слишком большим и перелива. С бесплатным паскалем ваш код вызывает ошибку 205 (переполнение с плавающей запятой). Это похоже на операцию 207 Invalid floating point - free pascal run-time error codes. Реальные типы, которые имеют отношение к вашему коду имеют следующие ограничения (со страницы free pascal data types вики):
Type Range Significant digits Bytes
Real platform dependent ??? 4 or 8
Single 1.5E-45 .. 3.4E38 7-8 4
Double 5.0E-324 .. 1.7E308 15-16 8
Extended 1.9E-4932 .. 1.1E4932 19-20 10
Обходной
Вам просто нужно учитывать возможность переполнения с вашим крупнейшим переменная. Невозможно просто проверить, превышает ли эта переменная максимальное значение, поэтому вы должны сделать обратную операцию, которая может вызвать переполнение. Я также использовал Extended
, чтобы получить более точную оценку.
var max_fat : Extended = 1.1 * power(10,4932);
var should_step : Extended= max_fat/(cont1)/(cont1-1)/(cont1-2)/(cont1-3);
затем в цикле в то время включать в себя проверку:
fat1 < should_step
В результате этой операции обратного является максимальным, что переменная fat1
может быть, прежде чем она переливается. Я использую математическую библиотеку, чтобы рассчитать максимум Extended
. Следующий тестовый код работает для меня:
program cosseno;
Uses Math;
var fat1, fat2, n1, n2, cont1, cont2, s, max_fat, should_step : Extended;
begin
s := 0.5;
fat1 := 24;
fat2 := 720;
n1 := 1/fat1;
n2 := 1/fat2;
cont1 := 8;
cont2 := 10;
max_fat := 1.1 * power(10,4932);
should_step := max_fat;
while ((n1 - n2) > 0.000001) AND (fat1 < should_step) do
begin
should_step := max_fat/(cont1)/(cont1-1)/(cont1-2)/(cont1-3);
fat1 := (cont1) * (cont1-1) * (cont1-2) * (cont1-3) * fat1;
fat2 := (cont2) * (cont2-1) * (cont2-2) * (cont2-3) * fat2;
cont1 := cont1 + 4;
cont2 := cont2 + 4;
n1 := n1 + 1/fat1;
n2 := n2 + 1/fat2;
writeln('fat1 > ', fat1);
writeln('fat2 > ', fat2);
writeln('cont1 > ', cont1);
writeln('cont2 > ', cont2);
writeln('n1 > ', n1);
writeln('n2 > ', n2);
end;
s := s + n1 - n2;
writeln('<==================>');
writeln(s);
end.
код дает следующий результат:
5.40302305868139717414E-0001
который я проверил, чтобы быть правильным, по крайней мере, первые 10 цифр.
Добро пожаловать в SO: SE. Пожалуйста, используйте форматирование «code», чтобы отобразить код и сделать его разборчивым. См. [Ask] и [Как отформатировать мои сообщения с помощью Markdown или HTML?] (Http://stackoverflow.com/help/formatting). – mins
Запустив этот код только в виду, я думаю, что fat2 будет иметь несколько перекрытий после нескольких циклов. Поместите заявление WriteLn в цикле, чтобы узнать, каков ваш последний ход. –
Когда вы просматриваете код с помощью отладчика, что он вам показывает? Какая строка в цикле 'while' вызывает ошибку? Каковы значения переменных, используемых в этой точке? –