perlnumber
СОДЕРЖАНИЕ
- ИМЯ
- СИНТЕКС
- ОПИСАНИЕ
- Хранение чисел
- Числовые операторы и числовые преобразования
- Разновидности числовых операций Perl
- АВТОР
- СМОТРИТЕ ТАКЖЕ
ИМЯ
perlnumber - семантика чисел и числовых операций в Perl
СИНТЕКС
$n = 1234; # decimal integer
$n = 0b1110011; # binary integer
$n = 01234; # octal integer
$n = 0x1234; # hexadecimal integer
$n = 12.34e-56; # exponential notation
$n = "-12.34e56"; # number specified as a string
$n = "1234"; # number specified as a string ОПИСАНИЕ
Этот документ описывает, как Perl обрабатывает числовые значения внутри.
Здесь полностью игнорируется механизм перегрузки операторов Perl. Перегрузка операторов позволяет определить пользовательское поведение для чисел, например, операции над произвольно большими целыми числами, числа с плавающей запятой произвольной точности, операции над «экзотическими» числами, такими как модулярная арифметика или p-адическая арифметика, и так далее. Подробности см. в overload.
Хранение чисел
Perl может внутренне представлять числа тремя различными способами: как целые числа, как числа с плавающей запятой и как десятичные строки. Десятичные строки могут иметь часть экспоненциальной записи, как в "12.34e-56". Нативное здесь означает «формат, поддерживаемый компилятором C, который использовался для построения perl».
Термин «нативный» не имеет такого же значения, когда мы говорим о нативных целых числах, как и когда речь идёт о нативных числах с плавающей запятой. Единственное следствие термина «нативный» для целых чисел заключается в том, что пределы максимального и минимального поддерживаемых истинных целочисленных значений близки к степеням 2. Однако «нативные» числа с плавающей запятой имеют наиболее фундаментальное ограничение: они могут представлять только те числа, которые имеют относительно «короткое» представление при преобразовании в двоичную дробь. Например, 0,9 не может быть представлен нативным числом с плавающей запятой, поскольку двоичная дробь для 0,9 бесконечна:
binary0.1110011001100... с последовательностью 1100 , повторяющейся снова и снова. В дополнение к этому ограничению, показатель двоичного числа также ограничен, когда он представлен как число с плавающей запятой. На типичных аппаратных средствах числа с плавающей запятой могут хранить числа с точностью до 53 двоичных разрядов и двоичными показателями от -1024 до 1024. В десятичной записи это примерно 16 десятичных разрядов и десятичные показатели в диапазоне -304..304. Всё это означает, что Perl не может сохранить число, такое как 12345678901234567, как число с плавающей запятой на таких архитектурах без потери информации.
Аналогично, десятичные строки могут представлять только те числа, которые имеют конечную десятичную запись. Будучи строками, и, следовательно, произвольной длины, нет практических ограничений на показатель или количество десятичных цифр для этих чисел. (Но помните, что мы обсуждаем правила только для хранения этих чисел. Тот факт, что вы можете хранить такие «большие» числа, не означает, что операции над этими числами будут использовать все значащие цифры. Подробности см. в разделе "Числовые операторы и числовые преобразования".)
На самом деле числа, хранящиеся в нативном целочисленном формате, могут храниться либо в знаковом нативном формате, либо в беззнаковом нативном формате. Таким образом, пределы чисел Perl, хранящихся как нативные целые числа, обычно составляют -2**31..2**32-1, с соответствующими изменениями в случае 64-битных целых чисел. Опять же, это не означает, что Perl может выполнять операции только над целыми числами в этом диапазоне: можно хранить гораздо больше целых чисел в формате с плавающей запятой.
Подводя итог, Perl числовые значения могут хранить только те числа, которые имеют конечную десятичную запись или «короткую» двоичную запись.
Числовые операторы и числовые преобразования
Как уже упоминалось, Perl может хранить число в любом из трёх форматов, но большинство операторов обычно понимают только один из этих форматов. При передаче числового значения в качестве аргумента такому оператору, оно будет преобразовано в формат, понятный оператору.
Возможны шесть таких преобразований:
native integer --> native floating point (*)
native integer --> decimal string
native floating_point --> native integer (*)
native floating_point --> decimal string (*)
decimal string --> native integer
decimal string --> native floating point (*) Эти преобразования регулируются следующими общими правилами:
-
Если исходное число может быть представлено в целевой форме, используется это представление.
-
Если исходное число выходит за пределы значений, представимых в целевой форме, используется представление ближайшего предела. (Потеря информации)
-
Если исходное число находится между двумя числами, представимыми в целевой форме, используется представление одного из этих чисел. (Потеря информации)
-
При преобразованиях, отмеченных
native floating point --> native integer, величина результата меньше или равна величине исходного значения. («Округление к нулю».) -
Если преобразование
decimal string --> native integerневозможно без потери информации, результат совместим с последовательностью преобразованийdecimal_string --> native_floating_point --> native_integer. В частности, округление сильно смещено в сторону 0, хотя число, такое как"0.99999999999999999999", может быть округлено до 1.
ОГРАНИЧЕНИЕ: Преобразования, отмеченные (*) выше, включают шаги, выполняемые компилятором C. В частности, ошибки/особенности используемого компилятора могут привести к нарушению некоторых из вышеуказанных правил.
Разновидности числовых операций Perl
Операции Perl, которые принимают числовой аргумент, обрабатывают этот аргумент одним из четырёх способов: они могут форсировать его в один из целочисленных/с плавающей запятой/строковых форматов или вести себя по-разному в зависимости от формата операнда. Принудительное преобразование числового значения в определённый формат не изменяет хранящееся в нём число.
Все операторы, которым нужен аргумент в целочисленном формате, обрабатывают аргумент как модульную арифметику, например, mod 2**32 на 32-битной архитектуре. sprintf "%u", -1 поэтому даёт тот же результат, что и sprintf "%u", ~0.
- Арифметические операторы
-
Бинарные операторы
+-*/%==!=><>=<=и унарные операторы-absи--будут пытаться преобразовать аргументы в целые числа. Если оба преобразования возможны без потери точности, и операция может быть выполнена без потери точности, то используется целочисленный результат. В противном случае аргументы преобразуются в формат с плавающей запятой, и используется результат с плавающей запятой. Кэширование преобразований (как описано выше) означает, что целочисленное преобразование не отбрасывает дробные части в числах с плавающей запятой. - ++
-
++ведёт себя как и другие операторы выше, за исключением того, что если это строка, соответствующая формату/^[a-zA-Z]*[0-9]*\z/, используется инкремент строки, описанный в perlop. -
Арифметические операторы во время
use integer -
В областях, где
use integer;в силе, почти все операторы, перечисленные выше, будут форсировать свой(и) аргумент(ы) в целочисленный формат и возвращать целочисленный результат. Исключение,abs,++и--, не меняют своего поведения сuse integer; - Другие математические операторы
-
Операторы, такие как
**,sinиexpфорсируют аргументы в формат с плавающей запятой. - Битовые операторы
-
Аргументы форсируются в целочисленный формат, если это не строки.
-
Битовые операторы во время
use integer -
принуждает аргументы к целочисленному формату. Также операции сдвига используют знакомые целые числа вместо по умолчанию беззнаковых.
- Операторы, которые ожидают целое число
-
принуждают аргумент к целочисленному формату. Это относится, например, к третьему и четвёртому аргументам
sysread. - Операторы, которые ожидают строку
-
принуждают аргумент к строковому формату. Например, это относится к
printf "%s", $value.
Хотя принудительное преобразование аргумента в определённый формат не изменяет хранящееся число, Perl запоминает результат таких преобразований. В частности, хотя первое такое преобразование может быть затратным по времени, повторные операции не потребуют повторного преобразования.
АВТОР
Илья Захаревич ilya@math.ohio-state.edu
Редакционные правки Гурсами Сарати <gsar@ActiveState.com>
Обновления для 5.8.0 Николасом Кларком <nick@ccl4.org>
СМОТРИТЕ ТАКЖЕ
© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/perlnumber