Spec-Zone.ru › Perl 5.38

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–2023 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.38.0/perlnumber

Spec-Zone.ru

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