¿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?


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).


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.


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

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".

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.