Spec-Zone.ru › Perl 5.32

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».

Термин «нативный» не имеет такого же значения применительно к целым числам, как применительно к числам с плавающей точкой. Единственное следствие термина «нативный» для целых чисел заключается в том, что пределы максимального и минимального поддерживаемых целочисленных значений близки к степеням двойки. Однако у «нативных» чисел с плавающей точкой есть существенное ограничение: они могут представлять только те числа, которые имеют относительно «короткое» представление при преобразовании в двоичную дробь. Например, 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

Редактирование экспертов Gurusamy Sarathy <gsar@ActiveState.com>

Обновления для 5.8.0 от Nicholas Clark <nick@ccl4.org>

СМОТРИТЕ ТАКЖЕ

overload, perlop

© 1993–2020 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.28.3/perlnumber

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API