2015-04-07 3 views
1
program cosseno; 
var fat1, fat2, n1, n2, cont1, cont2, s :real; 
begin 
    s := 0.5; 
    fat1 := 24; 
    fat2 := 720; 
    n1 := 1/fat1; 
    n2 := 1/fat2; 
    cont1 := 8; 
    cont2 := 10; 

    while (n1 - n2) > 0.000001 do 
    begin 
    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; 
    end; 

    s := s + n1 - n2; 
    writeln(s); 
end. 

Это программа для оценки значения e cos (1 рад), по-видимому, ошибка возникает в секции while.Почему я получаю ошибку 207 (недействительная операция с плавающей запятой)/Как обойти это?

+0

Добро пожаловать в SO: SE. Пожалуйста, используйте форматирование «code», чтобы отобразить код и сделать его разборчивым. См. [Ask] и [Как отформатировать мои сообщения с помощью Markdown или HTML?] (Http://stackoverflow.com/help/formatting). – mins

+2

Запустив этот код только в виду, я думаю, что fat2 будет иметь несколько перекрытий после нескольких циклов. Поместите заявление WriteLn в цикле, чтобы узнать, каков ваш последний ход. –

+0

Когда вы просматриваете код с помощью отладчика, что он вам показывает? Какая строка в цикле 'while' вызывает ошибку? Каковы значения переменных, используемых в этой точке? –

ответ

0

Проблема

Вопрос заключается в том, что ваша переменная 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 цифр.

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

  • Нет связанных вопросов^_^