Spec-Zone.ru › Perl 5.36

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

Редактирование перевода Гурсами Сарати <gsar@ActiveState.com>

Обновления для 5.8.0 Николасом Кларком <nick@ccl4.org>

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

overload, perlop

© 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.36.0/perlnumber

Spec-Zone.ru

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