Постановка задачи наталкивает нас на использование цикла с вещественным параметром, но цикл с параметром предполагает использование переменной порядкового типа, а тип 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.
Почему это происходит? Как вы знаете, вся информация представляется в памяти ЭВМ в виде 0 и 1. Для хранения переменной типа Real в памяти ЭВМ отводится 48 бит (6 байт), которая распределяется следующим образом:
Переведём вещественное число 0.1 в двоичную систему, для этого будем умножать число на 2:
Можно заметить, что полученная дробь является периодической с повторяющейся 0011. Согласно рис.4, мантисса 00000110011... обрывается после 40 разрядов. Таким образом, получаем приближённое представление вещественного числа.
Вернёмся к нашему примеру. Сейчас можем объяснить, почему первая программа работает не так, как нам бы хотелось - это происходит в силу приближённого представления вещественного числа. Поэтому при решении задач следует избегать использования циклов с изменяющейся вещественной переменной.
Пример 2
Дано х, принадлежащее интервалу от -1 до 1. Составить программу вычисления бесконечного ряда
х - х2/2 + х3/3 -... с заданной точностью Е.
Нужная точность считается полученной, если очередное слагаемое оказалось по модулю меньше, чем данное малое положительное число Е (это и все последующие слагаемые учитывать не надо).