¿Cuál es la diferencia entre `1L` y` 1`?

152

A menudo visto el símbolo 1L(o 2L, 3L, etc.) aparecen en código R. ¿Cuál es la diferencia entre 1Ly 1? 1==1Levalúa a TRUE. ¿Por qué se 1Lusa en el código R?

Zach
fuente
18
Nota: 1 == 1Lda TRUE, pero identical(1, 1L)da FALSE.
CJB
2
Ver también Aclaración de L en R
Henrik

Respuestas:

129

Entonces, @James y @Brian explicaron lo que significa 3L. ¿ Pero por qué lo usarías?

La mayoría de las veces no hace ninguna diferencia, pero a veces puede usarlo para que su código se ejecute más rápido y consuma menos memoria . Un vector doble ("numérico") usa 8 bytes por elemento. Un vector entero usa solo 4 bytes por elemento. Para vectores grandes, eso es menos memoria desperdiciada y menos espacio para la CPU (por lo que generalmente es más rápido).

Principalmente esto se aplica cuando se trabaja con índices. Aquí hay un ejemplo donde agregar 1 a un vector entero lo convierte en un vector doble:

x <- 1:100
typeof(x) # integer

y <- x+1
typeof(y) # double, twice the memory size
object.size(y) # 840 bytes (on win64) 

z <- x+1L
typeof(z) # still integer
object.size(z) # 440 bytes (on win64) 

... pero también tenga en cuenta que trabajar en exceso con enteros puede ser peligroso:

1e9L * 2L # Works fine; fast lean and mean!
1e9L * 4L # Ooops, overflow!

... y como señaló @Gavin, el rango para enteros es aproximadamente -2e9 a 2e9.

Sin embargo, una advertencia es que esto se aplica a la versión R actual (2.13). R podría cambiar esto en algún momento (los enteros de 64 bits serían geniales, lo que podría permitir vectores de longitud> 2e9). Para estar seguro, debe usar .Machine$integer.maxsiempre que necesite el valor entero máximo (y negarlo para el mínimo).

Tommy
fuente
1
Creo que los requisitos de memoria de R son los mismos independientemente del tipo, al menos según object.size. Para lo que es útil es pasar a Fortran o código C que puede requerir datos de un tipo particular.
James
2
No, intente object.size(1:100)vs object.size(1:100+0)400 bytes + algo de gastos generales frente a 800 bytes + algo de gastos generales. Actualicé el ejemplo anterior.
Tommy
2
Vale la pena mencionar que el desbordamiento de enteros se debe al uso de enteros con signo de 32 bits, por lo tanto restringido a aproximadamente +/- 2 * 10 ^ 9, incluso en R de 64 bits ...
Gavin Simpson
1
@Zach también es mucho más corto de escribir :-)
Gavin Simpson
1
@Gavin Simpson, por supuesto. Yo estaba realmente pensando en la situación en la que se crea un vector de todo, como c(1L, 2L, 3L, 4L,...100L)vs as.integer(c(1, 2, 3, 4,...100)).
Zach
54

De la sección de constantes de la definición del lenguaje R :

Podemos usar el sufijo 'L' para calificar cualquier número con la intención de convertirlo en un entero explícito. Entonces '0x10L' crea el valor entero 16 a partir de la representación hexadecimal. La constante 1e3L da 1000 como un número entero en lugar de un valor numérico y es equivalente a 1000L. (Tenga en cuenta que la 'L' se considera que califica el término 1e3 y no el 3.) Si calificamos un valor con 'L' que no es un valor entero, por ejemplo, 1e-3L, recibimos una advertencia y el valor numérico es creado. También se crea una advertencia si hay un punto decimal innecesario en el número, por ejemplo, 1.L.

Brian Gordon
fuente
46

L especifica un tipo entero, en lugar de un doble que es la clase numérica estándar.

> str(1)
 num 1
> str(1L)
 int 1
James
fuente
2

Para crear explícitamente un valor entero para una constante, puede llamar a la función as.integer o más, simplemente use el sufijo "L".

Eddy Zavala
fuente