Основные числовые типы данных (PascalABC.NET)
PascalABC.NET позволяет работать с большим количеством числовых типов, но пока обойдемся лишь двумя из них, которые будем считать основными.
В арифметике числа бывают целыми и нецелыми (их называют в программировании вещественными). Целое число внешне отличается тем, что не имеет дробной части. Например, число 10 для нас целое. Как и число 4. Но если требуется разделить 10 на 4, то можно получить три разных результата в зависимости от назначения деления.
- Если имеется 10 килограмм, сахара и надо развесить это количество поровну на 4 пакета, находим что 10 кг / 4 пакета = 2.5 кг/пакет. Мы получили нецелое число в результате деления двух целых чисел.
- Если имеется 10 яблок и нужно раздать их поровну 4 детям так, чтобы каждый получил равное количество целых яблок, выполняем деление нацело с недостатком, получая 10 яблок / 4 человека = 2 яблока/человека. Здесь результат целый и еще имеется остаток в 10 – 2 × 4 = 2 яблока.
- Если нужно испечь 10 пирогов, а в день можно испечь только 4, то понадобится 10 / 4 = 3 дня. Это целочисленное деление с избытком, потому что двух дней будет недостаточно.
Поучается, что в зависимости от ситуации мы решаем, как производить деление. Компьютер сам принимать решений не может, он лишь выполняет написанную нами программу. Поэтому нужно иметь возможность указывать в программе как производить деление. Разные языки программирования позволяют делать это разными способами.
В Паскале имеется операция целочисленного деления с недостатком div, но ее можно применять только к данным целого типа. Также, есть операция деления /, дающая вещественный результат для числовых данных любого типа. А вот операции деления нацело с избытком нет (впрочем, ее нет и в других широко известных языках программирования).
Тип real является более общим по отношению к integer, поэтому если возникает необходимость, компилятор сам вставляет преобразование integer к real. Наоборот поступать запрещено! Компилятор не имеет права преобразовать real к integer, поскольку при этом можно утратить дробную часть.
Данные целого типа (integer)
При записи значения предполагается, что если у него не указана дробная часть, значение имеет тип integer. Например, тип integer будут иметь числа 0, 15, -345, 1241, -12345678 и т.д. Для хранения таких чисел PascalABC.NET отводит 4 байта, поэтому числа должны укладываться в интервал [-2^31;2^31). Этому интервалу удовлетворяют значения от -2147483648 до 2147483647. Запомните примерное значение 2,1 миллиарда и ориентируйтесь на него при оценке.
Переполнение
Если написать 1291 * 1291 * 1291, то при построении кода программы компилятор «заметит», что результат для типа integer слишком велик и выдаст сообщение об ошибке «Переполнение в арифметической операции». Программа не будет откомпилирована и запустить ее не удастся. Но давайте обманем компилятор.
1 ##
2 var a := 1291;
3 Print(a * a * a);
Теперь компилятор «не видит» итогового выражения. Он определяет переменную a типа integer, заносит в нее значение 1291, а потом строит код для умножения. Поскольку a имеет тип integer, компилятор не видит причины изменять тип результата. Мина заложена. Она рванет, когда запустим программу. Запускаем. И вот оно: программа выдает значение -2143282125. Без особых проверок ясно, что значение неверно. Не может произведение трех положительных чисел быть отрицательным!
Операции
С целыми числами можно выполнять различные арифметические операции. Сложение (+), вычитание (-), умножение (*), целочисленное деление (div) и получение остатка от деления (mod) дают результат такого же типа integer. Можно изменять знак числа, указывая перед ним операцию «-» и она тоже дает результат типа integer. Операции деления (/) и возведения в степень (**) имеют тип real. О возведении в квадрат позаботились особо: его выполняет функция с именем Sqr, вот только результат ее выполнения имеет другой целочисленный тип – int64, поэтому если нужно возвести в квадрат некоторое k, лучше написать k * k и сохранить результату тип k.
Данные вещественного типа (real)
Значения данных типа real могут содержать дробную часть. Такие данные PascalABC.NET хранит в восьми байтах. Диапазон представления данных от -1.8∙10308 до 1.8∙10308, точность – 15 (иногда 16, но лучше на это не надеяться) цифр.
Вещественное число можно записывать с фиксированной точкой и с плавающей точкой.
Запись с фиксированной точкой – известная из математики запись числа, в которой целая и дробная части разделены точкой (она играет роль привычной нам запятой). Например, 13.123, -0.0023, 1.15, 5.0. Обратите внимание на последнее число – фактически, оно целое, но тип real требует указывать дробную часть, даже если она нулевая. Поэтому 5 – это тип integer, а 5.0 – тип real.
Операции
С вещественными числами типа real, как и с целыми, можно выполнять различные арифметические операции. Сложение (+), вычитание (-), умножение (*), деление (/) и возведение в степень (**) дают результат такого же типа real. И функция Sqr для возведения своего аргумента в квадрат, возвращает результат типа real. Можно изменять знак числа, указывая перед ним операцию «-» и она тоже даст результат типа real.
И 13 / 5, и 13 / 5.0, и 13.0 / 5 – все это деление вещественных чисел. Нужно делить нацело? Пишите 13 div 5. А можно ли написать 13 div 5.0? Написать можно, но операция деления нацело определена в Паскале только для случая, когда по обе стороны от div указаны целочисленные значения, так что компилятор сообщит вам все, что думает о вашем умении программировать.
Математический аналог представления числа с плавающей точкой вы тоже знаете: 1.3453∙10^-6, -3∙10^14 и т.п. Такие числа записываются в программе почти так же, как в математике, только вместо 10 указывается латинская буква E (или e). Приведенные выше числа можно записать в виде 1.3453E-6 и -3e14.
Использование значений с фиксированной и плавающей точкой в программе равноправно: это просто различные формы изображения одной и той же величины. Но все же, значение 0.0000000000012345 лучше писать как 1.2345e-12 или 12.345e-13. Запись короче и читать удобнее.
Несколько слов о выводе вещественных значений посредством процедур Write и Print. Если формат вывода не указан, для значений с абсолютной величиной на интервале [0.001 ; 1.0), будет использован формат с фиксированной точкой, а на интервале (0.0 ; 0.001) – формат с плавающей точкой. Если формат указан, точка будет всегда фиксированной.
1 ##
2 Writeln(1.2e-5, 1.2e-5:12:7); // 1.2E-05 0.0000120
3 Writeln(1.2e-2, 1.2e-2:12:7) // 0.012 0.0120000