Н. Вирт - Программирование на языке Модула-2 (1160777), страница 7
Текст из файла (страница 7)
Кнута "Искусствопрограммирования для ЭВМ" (М.:Мир, 1976,т. 1,с.68) - "наибольшее целое, меньшее или равноех". - Прим. перев.*) Операция MOD обозначает остаток целочисленного деления. Если мыопределимq = х DIV у,r = х MOD у,то будет выполняться соотношениех = q*y + r, 0 <= r < уЗначение х MOD у определено только для положительных х и у.Изменение знака обозначается унарной операцией - знаком минус. Кроме этой операциисуществуют еше две унарные операции ABS(x) и ODD(x). Первая дает абсолютное значениевеличины х, а вторая выдает результат типа BOOLEAN со значением "х нечетно".На каждой ЭВМ множество значений типа INTEGER ограничено некоторым конечныммножеством целых, обычно интервалом —2^(N-1)...2^(N—1)— 1, где N - небольшое целоечисло, часто 16 или 32, в зависимости от числа битов, используемых в ЭВМ для представленияцелых чисел. Если арифметическая операция выдает результат, лежащий за пределами этогодиапазона, то говорят, что возникло переполнение.
Вычислительная машина прореагирует на этособытие соответствующим образом, обычно прекращением процесса вычислений. Программистдолжен добиваться, чтобы при выполнении его программы переполнения не возникали.7.2. Тип CARDINAL (натуральный)Подобно типу INTEGER, тип CARDINAL представляет целые числа, но тольконеотрицательные значения, т.е. натуральные числа и 0. К этому типу применимы те же операции,что и к INTEGER.Тип CARDINAL по сравнению с INTEGER имеет то преимущество, что при егоиспользований явно выражается Факт неотрицательности переменной.
Мы рекомендуем типCARDINAL во всех случаях, когда отрицательные значения не будут (или не должны!)возникать....Явное исключение отрицательных значений из типа CARDINAL требует болеетщательного программирования. Например, программист, привыкший к типу INTEGER, вероятно,попадет в такую ловушку. Допустим, что оператор S должен выполняться в цикле с переменной 1,принимающей значения N-1,N-2,...,1,0.
Операторыi := N - 1;WHILE i >= 0 DOS; i := i - 1ENDбудут работать правильно, если i имеет тип INTEGER. Но в случае типа CARDINALпроизойдет ошибка, поскольку получится -1. Фактически выражение i >= 0 для i типа CARDINALвсегда истинно. Вот правильная форма этого фрагмента программы:i := N;WHILE i > 0 DO28i : = i — 1; SENDЕще одно преимущество использования типа CARDINAL состоит в том, чтовычислительная машина, использующая N битов для представления целых, обеспечит для типаCARDINAL диапазон 0 — 2^N-1, а максимальное значение INTEGER будет 2^(N-1)—1. Болеетого, умножение и деление обычно несколько быстрее выполняются над операндами типаCARDINAL.Модула не разрешает использовать операнды типа INTEGER и CARDINAL в одном и томже выражении (так называемые смешанные выражения).
Причина кроется в том, что машинныекоманды, реализующие операции, различны для этих двух типов. Ситуация несколько облегчаетсяприсутствием так называемых <ьункпий приведения. Если i имеет тип INTEGER, а с - типCARDINAL, то выражение i + с запрещено, i + INTEGER(c) будет иметь тип INTEGER, aCARDINAL(i) + с будет типа CARDINAL.7.3. Тип REAL (действительный)Значения типа REAL - действительные числа. Имеющиеся операции -это опять жеосновные арифметические операции и Функция ABS. Деление обозначается символом / (вместоDIV).Константы типа REAL характеризуются тем, что имеют десятичную точку и, возможно,десятичный пооядок. Вот примеры таких констант:1.5 1.50 1.5Е2 2.34Е-2 0.0Порядок состоит из прописной латинской буквы Е, за которойследует целое.
Это означает, что предшествующее действительноечисло должно быть умножено на 10 в степени "порядок". Следовательно,1.5Е2 = 150.0, 2.34Е-2 = 0.0234Важно помнить, что действительные числа представляются в машине как пары, состоящиеиз дробной части и порядка. Это называется представлением с плавающей точкой. Конечно, обечасти представления содержат конечное число цифр. Вследствие этого представлениедействительных чисел принципиально неточно, и в вычислениях, использующих такие значения,возникают погрешности, поскольку при выполнении операций может происходить округление илипотеря разрядов.Следующая программа делает очевидным наличие погрешностей, присущих операциям стипом REAL.
Эта программа вычисляет гармонический рядН(n) = 1 + 1/2 + 1/3 + ... + 1/nдвумя различными способами: один раз суммирование происходит слева направо, а другойраз - справа налево. Согласно законам арифметики, эти две суммы должны быть * равны. Однакоесли происходит потеря цифр (или даже округление), то суммы при больших п будут существенноразличаться. Правильный способ, очевидно, тот, который начинает с меньших слагаемых.MODULE ГармРяд;FROM InOut IMPORT ReadCard,Done,Write, WriteLn,WrlteString;FROM RealInOut IMPORT WriteReal;VAR i,n: CARDINAL;29x,d,sl,s2: REAL;BEGINWriteString("n="); ReadCard(n);WHILE Done DOs1 := 0.0; d := 0.0; i := 0; REPEATd := d + 1.0; i := i + 1; s1 := s1 + 1.0/d; UNTIL i >= n:WriteReal(sl,16); s2 := 0.0;REPEATs2 := S2 + 1.0/d; d := d - 1.0; i : = i-1;UNTIL i = 0;WriteReal(s2,16); WriteLn;WriteString("n="); ReadCard(n)END;WriteLnEND ГармРяд.Главная причина явного разделения действительных и целых чисел - их различноевнутреннее представление.
Значит, и арифметические операции для разных типов реализуютсяразными командами. Модула, следовательно,запрещаетвыражениясо смешаннымиоперандами.Можно, однако, преобразовать целые числа в действительные (более точно: внутреннеепредставление целых может быть преобразовано в представление с плавающей точкой) и обратноявными Функциями преобразования, а именноFLOAT(c) TRUNC(x)Функция FLOAT(c) имеет тип REAL и представляет значение величины с типаCARDINAL; TRUNC(x) представляет целую часть действительной величины х и имеет типCARDINAL. Программист должен иметь в виду, что различные реализации Модулы могутпредоставлять другие либо дополнительные Функции преобразования.7.4.
Тип BOOLEAN (логический)Значение типа BOOLEAN (булев, логический) имеет два логических, истинностныхзначения, обозначаемых стандартными идентификаторами TRUE и FALSE. Булевы переменныеобычно обозначаются идентификаторами, имеющими смысл прилагательных, причем значениеTRUE подразумевает наличие соответствующего свойства, a FALSE - его отсутствие. Имеетсянабор логических операций, которые вместе с переменными типа BOOLEAN образуют выраженияэтого типа. Логическими операциями являются AND (и) (обозначаемая также &), OR (или) и NOT(не) (обозначаемая также ~). Их смысл таков:р AND q = "как р, так и q равны TRUE"р OR q = "или р, или q, или оба равны TRUE"NOT p = "р равно FALSE"30Точное определение операций, однако, немного другое, хотя результат тот же:p AND q - IF p THEN q ELSE FALSEp OR q - IF p THEN TRUE ELSE qЭти определения подразумевают, - что второй операнд может и не вычисляться, еслирезультат уже известен после вычисления первого операнда.
Замечательное свойство этогоопределения заключается в том, что результат выражения может иметь смысл, даже если второйоперанд не определен. Как следствие этого порядок операторов может оказаться существенным.Иногда можно упростить логическое выражение применением простыхпреобразования. Особенно полезны законы де Моргана, задающие эквивалентностьправил(NOT p) AND (NOT q) = NOT (p OR q)(NOT p) OR (NOT q) = NOT (p AND q)Сравнения выдают результат типа BOOLEAN, т.е. TRUE, если сравнение справедливо, иFALSE - если нет. Например,7 = 12FALSE7 < 12TRUE1.5 >= 1.6 FALSEТакие сравнения синтаксически классифицируются как выражения, а два сравниваемыхоперанда - это простые выражения (см.
раздел, посвященный выражениям и операторам).Результат сравнения имеет тип BOOLEAN и может быть использован в управляющих структурах,таких, как условный оператор или операторы цикла. Знак # означает "не равно" (его синоним : <>).$Выражение = ПростоеВыражение$$[Сравнение ПростоеВыражение].Сравнение = "=" | "#" | "<>" | "<" | "<=" | ">" | ">=" |"IN".Следует отметить, что, подобно арифметическим операциям, среди логических операцийтоже имеется отношение старшинства.
NOT имеет наивысший приоритет, затем следует AND(называемая также логическим умножением), а затем OR (логическое сложение) и, наконец,операции сравнения. Как и в случае арифметических выражений, можно свободно применятьскобки, чтобы явно выразить связь между операциями. Вот примеры логических выражений:х=у(х <= у) & (у < z)(х > у) OR (у >= z)NOT p OR qЗаметим, что такая конструкция, как х < у AND z < w, запрещена.Значения типа BOOLEAN можно сравнивать, причем не только на равенство.
В частности,FALSE < TRUEСледовательно, логическая импликация "из р следует q* выражается или как(NOT р) OR q, или как p <= q.31Приведенные пример обращает внимание на правило, гласящее, что операнды операции(включая сравнения) должны иметь одинаковый тип. Значит, следующие сравнения неверны:1 = TRUE5 = 5.0i + j = p OR qНеверна также, например, запись: х <= у < z, которую можно развернуть в (х <= у) AND (у< z). Следующие логические выражения тем не менее верны:i+j<k-mp OR q = (i < j)И последнее замечание: хотя запись р = TRUE и верна, но так писать считается плохимстилем, лучше - просто р. Аналогично вместо р = FALSE лучше писать NOT p (или ~р).7.5 Тип CHAR (литерный)Любая вычислительная система осуществляет связь с окружающим ее миром черезнекоторые устройства ввода и вывода.