Quelle est la différence entre «1L» et «1»?


152

J'ai vu souvent le symbole 1L(ou 2L, 3L, etc.) apparaissent dans le code R. Quelle est la différence entre 1Let 1? 1==1Lévalue à TRUE. Pourquoi est-il 1Lutilisé dans le code R?


18
Remarque: 1 == 1Ldonne TRUE, mais identical(1, 1L)donne FALSE.
CJB

Réponses:


129

Ainsi, @James et @Brian ont expliqué ce que signifie 3L. Mais pourquoi l'utiliseriez-vous?

La plupart du temps, cela ne fait aucune différence, mais vous pouvez parfois l'utiliser pour que votre code s'exécute plus rapidement et consomme moins de mémoire . Un vecteur double ("numérique") utilise 8 octets par élément. Un vecteur entier utilise seulement 4 octets par élément. Pour les grands vecteurs, c'est moins de mémoire gaspillée et moins à parcourir pour le processeur (c'est donc généralement plus rapide).

Cela s'applique principalement lorsque vous travaillez avec des index. Voici un exemple où l'ajout de 1 à un vecteur entier le transforme en vecteur double:

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) 

... mais notez aussi que travailler trop avec des entiers peut être dangereux:

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

... et comme @Gavin l'a souligné, la plage des nombres entiers est d'environ -2e9 à 2e9.

Une mise en garde cependant est que cela s'applique à la version R actuelle (2.13). R pourrait changer cela à un moment donné (les entiers 64 bits seraient doux, ce qui pourrait activer des vecteurs de longueur> 2e9). Pour être sûr, vous devez utiliser .Machine$integer.maxchaque fois que vous avez besoin de la valeur entière maximale (et l'annuler pour le minimum).


1
Je pense que les besoins en mémoire de R sont les mêmes quel que soit le type, du moins selon object.size. Il est utile de passer au code Fortran ou C qui peut nécessiter des données d'un type particulier.
James

2
Non, essayez object.size(1:100)contre object.size(1:100+0)400 octets + une surcharge contre 800 octets + une surcharge. J'ai mis à jour l'exemple ci-dessus.
Tommy

2
Il convient de mentionner que le débordement d'entier est dû à l'utilisation d'entiers signés 32 bits, donc limités à environ +/- 2 * 10 ^ 9, même sur R 64 bits ...
Gavin Simpson

1
@Zach c'est aussi beaucoup plus court à taper :-)
Gavin Simpson

1
@Gavin Simpson bien sûr. Je pensais vraiment de la situation où vous créez un vecteur entier, comme c(1L, 2L, 3L, 4L,...100L)vs as.integer(c(1, 2, 3, 4,...100)).
Zach

54

À partir de la section Constantes de la définition du langage R :

Nous pouvons utiliser le suffixe «L» pour qualifier n'importe quel nombre dans le but d'en faire un entier explicite. Ainsi, «0x10L» crée la valeur entière 16 à partir de la représentation hexadécimale. La constante 1e3L donne 1000 comme un entier plutôt qu'une valeur numérique et équivaut à 1000L. (Notez que le 'L' est traité comme qualifiant le terme 1e3 et non le 3.) Si nous qualifions une valeur avec 'L' qui n'est pas une valeur entière, par exemple 1e-3L, nous obtenons un avertissement et la valeur numérique est établi. Un avertissement est également créé s'il y a un point décimal inutile dans le nombre, par exemple 1.L.


47

L spécifie un type entier, plutôt qu'un double, comme la classe numérique standard.

> str(1)
 num 1
> str(1L)
 int 1

2

Pour créer explicitement une valeur entière pour une constante, vous pouvez appeler la fonction as.integer ou plus simplement utiliser le suffixe "L".

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.