TURBO PASCAL

Новости           

Программы

Turbo Pascal

Игры

Документация

"Странности"

FAQ

Ссылки

Благодарности

Гостевая книга

От автора

Задание

Исследовать, что произойдёт, если:

формат указан больше, чем необходимо для изображения числа;
выводимое не будет помещаться в указанный формат (т.е. если число действительных разрядов в переменной окажется больше числа разрядов, выделенных для вывода переменной на экран);
у выводимого значения имеются дробные части, не укладывающаяся в заданное число позиций.

Пример 1

Напечатать таблицу значений функции y = Sin(x) на отрезке [0,1] с шагом 0.1 (считать, что при печати на каждое вещественное число отводится по 4 позиции строки).

Решение

Постановка задачи наталкивает нас на использование цикла с вещественным параметром, но цикл с параметром предполагает использование переменной порядкового типа, а тип Real таковым не является.

Сравните решение этой задачи, представленные ниже.

Program Example_21;
Var i : Real;
Begin
i:=0;
While i<=1 Do
Begin
Writeln(i:2:1,' ',sin(i):4:3);
i:=i+0.1;
End;
Readln;
End.

Program Example_22;
Var i: Integer;
Begin
i:=0
While i<=10 Do
Begin
Writeln(i,' ',sin(i/10):4:3);
Inc(i);
End;
Readln;
End.

На первый взгляд, работа этих программ должна быть одинаковой, но, запустив программы, мы обнаружим, что первая программа выдает значения функции sin(x) для всех значений х от 0 до 0.9, а вторая программа - для всех значений х от 0 до 1.

Рисунок 4

Почему это происходит? Как вы знаете, вся информация представляется в памяти ЭВМ в виде 0 и 1. Для хранения переменной типа Real в памяти ЭВМ отводится 48 бит (6 байт), которая распределяется следующим образом:

Переведём вещественное число 0.1 в двоичную систему, для этого будем умножать число на 2:

0.1 * 2 = 0.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6
0.6 * 2 = 1.2
0.2 * 2 = 0.4

далее вычисления повторяются.

Выписывая подчёркнутые цифры, получим двоичную дробь:

0.110 = 0.0001100110011...2.

Можно заметить, что полученная дробь является периодической с повторяющейся 0011. Согласно рис.4, мантисса 00000110011... обрывается после 40 разрядов. Таким образом, получаем приближённое представление вещественного числа.

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

Пример 2

Дано х, принадлежащее интервалу от -1 до 1. Составить программу вычисления бесконечного ряда

х - х2/2 + х3/3 -... с заданной точностью Е.

Нужная точность считается полученной, если очередное слагаемое оказалось по модулю меньше, чем данное малое положительное число Е (это и все последующие слагаемые учитывать не надо).

Решение

На первый взгляд программа должна вычислять очередное слагаемое хn/n и прибавлять его к сумме, полученное на предыдущем этапе. При нахождении значения хn можно воспользоваться циклом с параметром, но, с другой стороны, чтобы вычислить значения хn достаточно значение х n-1 (найдено на предыдущем шаге) умножить на х.

Вопросы для обсуждения

  1. Как можно запрограммировать смену знака слагаемого?
  2. Какой конструкцией необходимо воспользоваться для нужной точности приближения?
  3. Сколько переменных необходимо для решения задачи, каковы их начальные значения?

Итак, решение будет выглядеть следующим образом:

Program Example_23;
Var x, st, sl, y, e: Real;
n, z, : Integer;
Begin
Write ('Введите х, принадлежащее (-1,1)' ); Readln(x);
Write ('Введите погрешность вычисления ' ); Readln( e );
y:=0; n:=1; z:=1; st:=x; sl:=x;
Repeat
Inc (y, z*sl); Inc (n); z:=-z; st:=st*x; sl:=st/n;
Until sl<e;
Writeln (y); Readln;
End.

Содержание

На главную страницу
(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

    Rambler's Top100 PROext: Top 1000
    Rambler's Top100 Яндекс цитирования
Hosted by uCoz