En informática , un literal entero es una especie de literal para un entero cuyo valor se representa directamente en el código fuente . Por ejemplo, en la instrucción de asignación x = 1
, la cadena 1
es un literal entero que indica el valor 1, mientras que en la instrucción x = 0x10
la cadena 0x10
es un literal entero que indica el valor 16, que está representado por 10
en hexadecimal (indicado por el 0x
prefijo).
Por el contrario, en x = cos(0)
, la expresión se cos(0)
evalúa como 1 (como el coseno de 0), pero el valor 1 no se incluye literalmente en el código fuente. Más simplemente, en x = 2 + 2,
la expresión se 2 + 2
evalúa a 4, pero el valor 4 no se incluye literalmente. Además, en x = "1"
el "1"
es un literal de cadena , no un literal entero, porque está entre comillas. El valor de la cadena es 1
, que resulta ser una cadena entera, pero este es un análisis semántico del literal de cadena; en el nivel sintáctico "1"
es simplemente una cadena, no es diferente de "foo"
.
Analizando
Reconocer una cadena (secuencia de caracteres en el código fuente) como un literal entero es parte de la fase de análisis léxico (lexing), mientras que evaluar el literal a su valor es parte de la fase de análisis semántico . Dentro del lexer y la gramática de frases, la clase de token a menudo se denota integer
, y las minúsculas indican una clase de token de nivel léxico, en contraposición a la regla de producción de nivel de frase (como ListOfIntegers
). Una vez que una cadena ha sido lexada (tokenizada) como un literal entero, su valor no se puede determinar sintácticamente (es solo un número entero), y la evaluación de su valor se convierte en una pregunta semántica.
Los literales enteros generalmente se combinan con expresiones regulares , como en Python . [1]
Evaluación
Al igual que con otros literales, los literales enteros generalmente se evalúan en tiempo de compilación, como parte de la fase de análisis semántico. En algunos casos, este análisis semántico se realiza en el lexer, inmediatamente después del reconocimiento de un literal entero, mientras que en otros casos se difiere hasta la etapa de análisis sintáctico, o hasta después de que el árbol de análisis sintáctico se haya construido por completo. Por ejemplo, al reconocer la cadena, 0x10
el lexer podría evaluar inmediatamente esto a 16 y almacenar eso (una ficha de tipo integer
y valor 16), o aplazar la evaluación y, en su lugar, registrar una ficha de tipo integer
y valor 0x10
.
Una vez que se han evaluado los literales, es posible un análisis semántico adicional en forma de plegado constante , lo que significa que las expresiones literales que involucran valores literales se pueden evaluar en la fase de compilación. Por ejemplo, en la declaración x = 2 + 2
después de que se hayan evaluado los literales y 2 + 2
se haya analizado la expresión , se puede evaluar a 4, aunque el valor 4 no aparece en sí mismo como literal.
Afijos
Los literales enteros suelen tener prefijos que indican la base y, con menor frecuencia, sufijos que indican el tipo. [1] Por ejemplo, en C ++ 0x10ULL
indica el valor 16 (porque es hexadecimal) como un entero largo sin signo.
Los prefijos comunes incluyen:
0x
o0X
para hexadecimal (base 16);0
,0o
o0O
para octal (base 8);0b
o0B
para binario (base 2).
Los sufijos comunes incluyen:
l
oL
para entero largo;ll
oLL
para entero largo;u
oU
para entero sin signo.
Estos afijos son algo similares a los sigilos , aunque los sigilos se unen a identificadores (nombres), no a literales.
Separadores de dígitos
En algunos idiomas, los literales enteros pueden contener separadores de dígitos para permitir la agrupación de dígitos en formas más legibles. Si está disponible, normalmente también se puede hacer para literales de punto flotante. Esto es particularmente útil para campos de bits y facilita ver el tamaño de números grandes (como un millón) de un vistazo subitizando en lugar de contar dígitos. También es útil para números que suelen estar agrupados, como el número de tarjeta de crédito o los números de la seguridad social . [a] Los números muy largos se pueden agrupar aún más duplicando los separadores.
Normalmente, los números decimales (base-10) se agrupan en grupos de tres dígitos (que representan uno de 1000 valores posibles), números binarios (base-2) en grupos de cuatro dígitos (un nibble , que representa uno de los 16 valores posibles) y números hexadecimales ( base-16) en grupos de dos dígitos (cada dígito es un nibble, por lo que dos dígitos son un byte , lo que representa uno de los 256 valores posibles). Los números de otros sistemas (como los números de identificación) se agrupan siguiendo cualquier convención que esté en uso.
Ejemplos de
En Ada , [2] [3] C # (desde la versión 7.0), D , Eiffel , Go (desde la versión 1.13), [4] Haskell (desde la versión 8.6.1 de GHC), [5] Java (desde la versión 7), [6] Julia , Perl , Python (de la versión 3.6), [7] Ruby , Rust [8] y Swift , [9] los literales enteros y los literales flotantes se pueden separar con un guión bajo ( _
). Puede haber algunas restricciones de ubicación; por ejemplo, en Java no pueden aparecer al principio o al final del literal, ni al lado de un punto decimal. Tenga en cuenta que si bien el punto, la coma y los espacios (finos) se utilizan en la escritura normal para la separación de dígitos, estos entran en conflicto con su uso existente en lenguajes de programación como punto de base , separador de lista (y en C / C ++, el operador de coma ) y separador de tokens.
Ejemplos incluyen:
int oneMillion = 1_000_000 ; int creditCardNumber = 1234_5678_9012_3456 ; int socialSecurityNumber = 123_45_6789 ;
En C ++ 14 (2014), el carácter de apóstrofe se puede usar para separar dígitos arbitrariamente en literales numéricos. [10] El guión bajo se propuso inicialmente, con una propuesta inicial en 1993, [11] y nuevamente para C ++ 11 , [12] después de otros lenguajes. Sin embargo, esto provocó un conflicto con los literales definidos por el usuario , por lo que se propuso el apóstrofo en su lugar, como una " coma superior " (que se utiliza en algunos otros contextos). [13] [14]
auto integer_literal = 1'000'000 ; auto binary_literal = 0b0100'1100'0110 ; auto very_long_binary_literal = 0b0000'0001'0010'0011 '' 0100'0101'0110'0111 ;
Notas
- ^ Sin embargo, los números normalmente confidenciales como estos no se incluirían como literales.
Referencias
- ^ a b " 2.4.4. Literales enteros y enteros largos "
- ^ "Manual de referencia del lenguaje Ada '83: 2.4. Literales numéricos" .
- ^ " " Justificación del diseño del lenguaje de programación Ada® ": 2.1 Estructura léxica" .
- ^ "Notas de la versión Go 1.13 - Cambios en el idioma" . Consultado el 5 de noviembre de 2020 .
- ^ "Guía del usuario del compilador de Glasgow Haskell: 11.3.7. Guiones bajos numéricos" . Consultado el 31 de enero de 2019 .
- ^ "Guiones bajos en literales numéricos" . Consultado el 12 de agosto de 2015 .
- ^ "Novedades de Python 3.6" .
- ^ "Literales y operadores" . Consultado el 15 de noviembre de 2019 .
- ^ "El lenguaje de programación Swift: estructura léxica" .
- ^ Crowl, Lawrence; Smith, Richard; Snyder, Jeff; Vandevoorde, Daveed (25 de septiembre de 2013). "N3781 Comillas simples como separador de dígitos" (PDF) .
- ^ John Max Skaller (26 de marzo de 1993). "N0259: Una propuesta para permitir literales binarios y algunos otros pequeños cambios en el Capítulo 2: Convenciones léxicas" (PDF) .
- ^ Crowl, Lawrence (2 de mayo de 2007). "N2281: Separadores de dígitos" .
- ^ Vandevoorde, Daveed (21 de septiembre de 2012). "N3448: separación indolora de dígitos" (PDF) .
- ^ Crowl, Lawrence (19 de diciembre de 2012). "N3499: Separadores de dígitos" .