Целое (тип данных)

Эта статья находится на начальном уровне проработки, в одной из её версий выборочно используется текст из источника, распространяемого под свободной лицензией
Материал из энциклопедии Руниверсалис
(перенаправлено с «Целочисленный тип»)

Целое, целочисленный тип данных (англ. integer) — один из самых простых примитивных типов данных. Служит для представления целых чисел, ограниченного минимальным и максимальным значением, зависящими от выделенной под число памяти.

Разновидности

Как правило, для большинства задач используется целочисленный тип, называемый также native int (или просто int), с разрядностью, равной разрядности машинного слова процессора, на котором исполняется программа (или режима работы процессора если он может работать с машинными словами разной длины). При необходимости могут использоваться целые числа как меньшей (например, при необходимости экономить память), так и бо́льшей (при использовании длинной арифметики) разрядности. Другая возможная причина использования целых отличной от родной длины — обеспечение переносимости данных. Наиболее распространённые разновидности целого:

  • однобайтное целое (англ. tiny int) — 8 бит, -128 ÷ 127;
  • короткое целое (англ. short int) — 16 бит, −32 768 ÷ 32 767;
  • длинное целое (англ. long int, также int32) — 32 бита, −2 147 483 648 (−231) ÷ 2 147 483 647 (231−1);
  • двойное длинное целое (англ. long long int, также large int, big int, int64) — 64 бита, -9 223 372 036 854 775 808 (−263) ÷ 9 223 372 036 854 775 807 (263−1);

Также если необходимо экономить память, но нет необходимости в представлении отрицательных чисел, могут использоваться беззнаковые (unsigned) целые, что позволяет увеличить максимально возможное значение вдвое и ещё на единицу: например, беззнаковым коротким целым можно представить число от 0 до 65 535. Иногда в литературе[1] встречаются рекомендации не использовать беззнаковые целые, поскольку он может быть не реализован процессором компьютера. Также поддержка беззнаковых типов отсутствует в некоторых языках программирования, например в Java[2].

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

Представление

В памяти целое число хранится как последовательность битов, разбитая на байты (октеты). Порядок следования байтов может быть как прямым (англ. big-endian), от старшего разряда к младшему, так и обратным (англ. little-endian).

Представление знака тоже может различаться для разных архитектур. Наиболее распространён так называемый дополнительный код, при котором отрицательное число представлено вычитанием из 0 с переполнением, при этом если старший бит старшего байта включён — число считается отрицательным. Реже используются обратный код (когда отрицательное число представлено как побитовая инверсия положительного), прямой код (когда отрицательное число представлено как положительное со включённым битом знака) или более экзотические, такие как система счисления по основанию −2[3].

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

Операции над целыми

Арифметические операции

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

  • Сравнение (англ. comparison). Здесь применимы соотношения «равно» («=»; «==»; «eq»), «не равно» («!=»; «<>»; «ne»), «больше» («>»; «gt»), «больше или равно» («>=»; «ge»), «меньше» («<»; «lt») и «меньше или равно» («<=»; «le»).
  • Инкремент (англ. increment; «++») и декремент (англ. decrement; «--») — арифметическое увеличение или уменьшение числа на единицу. Выделено в отдельные операции из-за частого использования с переменными-счётчиками в программировании.
  • Сложение (англ. addition; «+») и вычитание (англ. subtraction; «-»).
  • Умножение (англ. multiplication; «*»).
  • Деление (англ. division; «/»; «\») и получение остатка от деления (англ. modulo; «%»). Некоторые процессоры (например, архитектуры x86) позволяют производить обе эти операции за одну инструкцию.
  • Инверсия знака (англ. negation) и получение абсолютного значения (англ. absolute).
  • Получение знака. Результатом такой операции обычно является 1 для положительных значений, −1 — для отрицательных и 0 — для нуля.
  • Возведение в степень («^»).

В некоторых языках программирования для лаконичности есть операторы, которые позволяют производить арифметическую операцию с присвоением. Например, «+=» складывает текущее значение переменной слева с выражением справа и помещает результат в исходную переменную. Так же в некоторых языках и средах доступна совмещённая операция MulDiv, которая умножает на одно число, а потом делит результат на второе.

Обычно самыми дорогими по скорости операциями являются умножение и деление (получение остатка от деления).

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

  • Циклическая операция (обычно происходит по умолчанию). Например, если сделать инкремент 8-битного беззнакового значения 255, то получится 0.
  • Операция с насыщением. Если будет достигнут предел, то конечным значением будет это предельное. Например, если к 8-битному беззнаковому числу 250 прибавить 10, то получится 255. Сложение, вычитание и умножение с насыщением обычно применяется при работе с цветом.

Побитовые операции

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

  • Битовый сдвиг влево с дополнением нулями аналогичен умножению числа на степень двойки (количество бит сдвига соответствует степени двойки).
  • Битовый сдвиг вправо аналогичен делению на степень двойки (количество бит сдвига соответствует степени двойки). Некоторые языки программирования и процессоры поддерживают арифметический сдвиг, который позволяет сохранять знак у целых со знаком (сохраняется значение старшего бита).
  • У целых со знаком знак можно узнать по старшему биту (у отрицательных он установлен).
  • Чтение и установка младшего бита позволяет управлять чётностью (у нечётных чисел он установлен).
  • Побитовое «И» над определённым количеством младших бит позволяет узнать остаток от деления на степень двойки (степень соответствует количеству бит).
  • Побитовое «ИЛИ» над определённым количеством младших бит и последующий инкремент округляет число на значение, равное степени двойки (степень соответствует количеству бит) — используется для выравнивания адресов и размеров на определённое значение.

Работа со строками

Довольно частыми операциями являются получение строки из числового значения во внутреннем представлении и обратно — число из строки. При преобразовании в строку обычно доступны средства задания форматирования в зависимости от языка пользователя.

Ниже перечислены некоторые из представлений чисел строкой.

  • Десятичное число (англ. decimal). При получении строки обычно можно задать разделители разрядов, количество знаков (добавляются лидирующие нули, если их меньше) и обязательное указание знака числа.
  • Число в системе счисления, которое является степенью двойки. Самые частые: двоичное (binary англ. binary), восьмеричное (англ. octal) и шестнадцатеричное (англ. hexadecimal). При получении строки обычно можно задать разделители групп цифр и минимальное количество цифр (производится дополнение нулями, если их меньше). Так как эти представления чаще всего используются в программировании, то здесь обычно доступны соответствующие опции. Например, указание префикса и постфикса для получения значения в соответствии с синтаксисом языка. Для 16-ричных актуально указание регистра символов, а также обязательное добавление нуля, если первая цифра представлена буквой (чтобы число не определялось как строковый идентификатор).
  • Римское число (англ. roman number).
  • Словесное представление (в том числе сумма прописью) — число представляется словами на указанном натуральном языке.

Перечислимый тип

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

Например, в языке Python логический тип является подтипом целого и использует имена False и True, которые при приведении к целому получают значения 0 и 1 соответственно[4].

Примечания

  1. Бен-Ари, 2000, с. 54.
  2. Types, Values and Variables, Java Languaege Specification, 2-nd ed.
  3. Hacker's Delight, 2004, с. 215—221.
  4. Beazley, 2009, pp. 38.

Литература