Основные числовые типы данных (PascalABC.NET): различия между версиями

Материал из Информационная безопасностя
Перейти к навигации Перейти к поиску
Строка 11: Строка 11:
 
В Паскале имеется операция целочисленного деления с недостатком div, но ее можно применять только к данным целого типа. Также, есть операция деления /, дающая вещественный результат для числовых данных любого типа. А вот операции деления нацело с избытком нет (впрочем, ее нет и в других широко известных языках программирования).
 
В Паскале имеется операция целочисленного деления с недостатком div, но ее можно применять только к данным целого типа. Также, есть операция деления /, дающая вещественный результат для числовых данных любого типа. А вот операции деления нацело с избытком нет (впрочем, ее нет и в других широко известных языках программирования).
  
<div style="font-size: 1.3em;">Для PascalABC.NET пока примем, что целые числовые данные имеют тип integer, а вещественные – тип real. <div>
+
<div style="font-size: 1.3em;">Для PascalABC.NET пока примем, что целые числовые данные имеют тип <span style="font-weight: bold;"> integer</span>, а вещественные – тип <span style="font-weight: bold;">real</span>. <div>
  
 
Тип real является более общим по отношению к integer, поэтому если возникает необходимость, компилятор сам вставляет преобразование integer к real. Наоборот поступать запрещено! Компилятор не имеет права преобразовать real к integer, поскольку при этом можно утратить дробную часть.
 
Тип real является более общим по отношению к integer, поэтому если возникает необходимость, компилятор сам вставляет преобразование integer к real. Наоборот поступать запрещено! Компилятор не имеет права преобразовать real к integer, поскольку при этом можно утратить дробную часть.

Версия 07:38, 4 мая 2023

PascalABC.NET позволяет работать с большим количеством числовых типов, но пока обойдемся лишь двумя из них, которые будем считать основными.

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

  1. Если имеется 10 килограмм, сахара и надо развесить это количество поровну на 4 пакета, находим что 10 кг / 4 пакета = 2.5 кг/пакет. Мы получили нецелое число в результате деления двух целых чисел.
  2. Если имеется 10 яблок и нужно раздать их поровну 4 детям так, чтобы каждый получил равное количество целых яблок, выполняем деление нацело с недостатком, получая 10 яблок / 4 человека = 2 яблока/человека. Здесь результат целый и еще имеется остаток в 10 – 2 × 4 = 2 яблока.
  3. Если нужно испечь 10 пирогов, а в день можно испечь только 4, то понадобится 10 / 4 = 3 дня. Это целочисленное деление с избытком, потому что двух дней будет недостаточно.

Поучается, что в зависимости от ситуации мы решаем, как производить деление. Компьютер сам принимать решений не может, он лишь выполняет написанную нами программу. Поэтому нужно иметь возможность указывать в программе как производить деление. Разные языки программирования позволяют делать это разными способами.

В Паскале имеется операция целочисленного деления с недостатком div, но ее можно применять только к данным целого типа. Также, есть операция деления /, дающая вещественный результат для числовых данных любого типа. А вот операции деления нацело с избытком нет (впрочем, ее нет и в других широко известных языках программирования).

Для PascalABC.NET пока примем, что целые числовые данные имеют тип integer, а вещественные – тип real.

Тип 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