perlnumber - Semántica de números y operaciones numéricas en Perl
$n = 1234; # entero decimal $n = 0b1110011; # entero binario $n = 01234; # entero octal $n = 0x1234; # entero hexadecimal $n = 12.34e-56; # notación exponencial $n = "-12.34e56"; # número especificado como una cadena $n = "1234"; # número especificado como una cadena
En este documento se describe el procesamiento interno de valores numéricos en Perl.
Se omite completamente la funcionalidad de sobrecarga de operadores de Perl, que permite establecer comportamientos definidos por el usuario para números, como operaciones con enteros arbitrariamente grandes, números de punto flotante de precisión arbitraria, operaciones con números "exóticos" (como la aritmética modular o la aritmética de números p-ádicos), etc. Encontrará información detallada en overload.
Perl puede representar los números internamente de 3 maneras distintas: como enteros nativos, como números de punto flotante nativos y como cadenas decimales. Las cadenas decimales pueden tener una parte en notación exponencial (por ejemplo, "12.34e-56"). Aquí nativo significa "formato admitido por el compilador de C que se usó para compilar perl".
"12.34e-56"
En el caso de los enteros nativos, el término "nativo" no tiene las mismas implicaciones que para los números de punto flotante nativos. La única implicación del término "nativo" para los enteros es que los límites máximo y mínimo de las cantidades verdaderamente enteras admitidas son cercanos a potencias de 2. En cambio, existe una restricción intrínseca para los números de punto flotante "nativos": solo se pueden representar los números que tengan una representación relativamente "corta" al convertirse en una fracción binaria. Por ejemplo, 0.9 no se puede representar como un número de punto flotante nativo porque la fracción binaria correspondiente a 0.9 es infinita:
binary0.1110011001100...
donde la secuencia 1100 se repite una y otra vez. Además de esta limitación, el exponente del número binario también está restringido cuando se representa como un número de punto flotante. En el hardware típico, los valores de punto flotante pueden almacenar números que tengan hasta 53 dígitos binarios, y con exponentes binarios entre -1024 y 1024. En representación decimal, estos límites se acercan a 16 dígitos decimales y exponentes decimales en el intervalo -304..304. Como consecuencia, Perl no puede almacenar un número como 12345678901234567 en forma de número de punto flotante para estas arquitecturas sin pérdida de información.
1100
De manera similar, las cadenas decimales solo pueden representar números que tengan una expansión decimal finita. Al ser cadenas y, por tanto, al tener una longitud arbitraria, no existe un límite práctico para el exponente o el número de dígitos decimales para estos números. (Pero no olvide que lo que estamos describiendo son solo las normas del almacenamiento de estos números. El hecho de poder almacenar números tan "grandes" no significa que en las operaciones con estos números se usen todos los dígitos significativos. Encontrará información detallada en "Operadores numéricos y conversiones numéricas".)
De hecho, los números almacenados en formato de entero nativo se pueden almacenar en forma nativa con signo o sin signo. Así, los límites para números Perl almacenados como enteros nativos serán normalmente -2**31..2**32-1, con las modificaciones correspondientes en el caso de los enteros de 64 bits. Insistimos: esto no significa que Perl sólo puede realizar operaciones con enteros de este intervalo; es posible almacenar muchos más enteros en formato de punto flotante.
En resumen, en Perl los valores numéricos solo pueden almacenar números que tengan una expansión decimal finita o una expansión binaria "corta".
Como se mencionó antes, Perl puede almacenar un número en uno de tres formatos distintos, pero la mayoría de los operadores suelen admitir solo uno de esos formatos. Cuando se pasa un valor numérico como argumento a un operador así, se convierte a un formato comprensible para el operador.
Hay seis conversiones posibles:
entero nativo --> punto flotante nativo (*) entero nativo --> cadena decimal punto flotante nativo --> entero nativo (*) punto flotante nativo --> cadena decimal (*) cadena decimal --> entero nativo cadena decimal --> punto flotante nativo (*)
Estas conversiones obedecen las siguientes normas generales:
Si el número de origen se puede representar en la forma de destino, se usa esa representación.
Si el número de origen está fuera de los límites representables en la forma de destino, se usa una representación del límite más cercano. (Pérdida de información)
Si el número de origen está entre dos números representables en la forma de destino, se usa una representación de uno de estos números. (Pérdida de información)
En las conversiones punto flotante nativo --> entero nativo, la magnitud del resultado es menor o igual que la magnitud del número de origen. ("Redondeo a cero")
punto flotante nativo --> entero nativo
Si no se puede aplicar la conversión cadena decimal --> entero nativo sin pérdida de información, el resultado es compatible con la secuencia de conversiones cadena decimal --> punto flotante nativo --> entero nativo. En particular, hay un sesgo muy fuerte de redondeo a 0, aunque es posible que un número como "0.99999999999999999999" se redondee a 1.
cadena decimal --> entero nativo
cadena decimal --> punto flotante nativo --> entero nativo
"0.99999999999999999999"
RESTRICCIÓN: las conversiones anteriores marcadas con (*) implican pasos ejecutados por el compilador de C. En particular, determinados errores o características del compilador usado pueden provocar la infracción de algunas de las normas anteriores.
(*)
En Perl, las operaciones que consumen un argumento numérico tratan al argumento de una de cuatro maneras posibles: pueden forzar la conversión a uno de los formatos de entero/número de punto flotante/cadena, o pueden comportarse de una manera diferente en función del formato del operando. Forzar la conversión de un valor numérico a un formato específico no cambia el número almacenado en el valor.
Todos los operadores que necesitan un argumento con formato de entero tratan al argumento como en la aritmética modular (p. ej., mod 2**32 en una arquitectura de 32 bits). Así, sprintf "%u", -1 produce el mismo resultado que sprintf "%u", ~0.
mod 2**32
sprintf "%u", -1
sprintf "%u", ~0
Los operadores binarios + - * / % == != > < >= y <=, y los operadores unarios abs y --, intentan convertir los argumentos en enteros. Si ambas conversiones son posibles sin pérdida de precisión y se puede realizar la operación sin pérdida de precisión, se usa el resultado entero. De lo contrario, los argumentos se convierten al formato de punto flotante y se usa el resultado de punto flotante. El almacenamiento en caché de las conversiones descritas arriba significa que la conversión a enteros no desecha las partes fraccionarias en los números de punto flotante.
+
-
*
/
%
==
!=
>
<
>=
<=
abs
--
++ se comporta como los operadores anteriores, con la diferencia de que si se aplica a una cadena que tenga el formato /^[a-zA-Z]*[0-9]*\z/, se usa el incremento de cadena descrito en perlop.
++
/^[a-zA-Z]*[0-9]*\z/
use integer
En ámbitos en los que use integer; está activo, casi todos los operadores indicados arriba forzarán la conversión de sus argumentos a formato de entero, y devolverán un resultado entero. Las excepciones son abs, ++ y --, que no cambian su comportamiento con use integer;
use integer;
Algunos operadores, como **, sin y exp, fuerzan la conversión de los argumentos al formato de punto flotante.
**
sin
exp
Fuerzan la conversión de los argumentos al formato de entero si no son cadenas.
Fuerzan la conversión de los argumentos al formato de entero. Además, las operaciones de desplazamiento usan internamente enteros con signo en lugar de los enteros sin signo predeterminados.
Fuerzan la conversión del argumento al formato de entero. Esto es aplicable, por ejemplo, a los argumentos tercero y cuarto de sysread.
sysread
Fuerzan la conversión del argumento al formato de cadena. Por ejemplo, esto es aplicable a printf "%s", $valor.
printf "%s", $valor
Aunque forzar la conversión de un argumento a un formato específico no cambia el número almacenado, Perl recuerda el resultado de las conversiones. Así, aunque la primera conversión tarde un poco más, al repetir una operación no será necesario repetir la conversión.
Ilya Zakharevich ilya@math.ohio-state.edu
ilya@math.ohio-state.edu
Ajustes editoriales de Gurusamy Sarathy <gsar@ActiveState.com>
Actualizaciones para 5.8.0 de Nicholas Clark <nick@ccl4.org>
overload, perlop
Joaquín Ferrero (Tech Lead), explorer + POD2ES at joaquinferrero.com
explorer + POD2ES at joaquinferrero.com
Enrique Nell (Language Lead), blas.gordon + POD2ES at gmail.com
blas.gordon + POD2ES at gmail.com
1 POD Error
The following errors were encountered while parsing the POD:
Non-ASCII character seen before =encoding in 'Semántica'. Assuming CP1252
To install POD2::ES, copy and paste the appropriate command in to your terminal.
cpanm
cpanm POD2::ES
CPAN shell
perl -MCPAN -e shell install POD2::ES
For more information on module installation, please visit the detailed CPAN module installation guide.