web-dev-qa-db-fra.com

Pourquoi R utiliserait-il le suffixe "L" pour désigner un entier?

Dans R, nous savons tous que c'est pratique pour les moments où nous voulons nous assurer que nous avons affaire à un entier pour le spécifier en utilisant le "L" suffixe comme ceci:

1L
# [1] 1

Si nous ne disons pas explicitement à R que nous voulons un entier, il supposera que nous voulions utiliser un type de données numeric ...

str( 1 * 1 )
# num 1
str( 1L * 1L )
# int 1

Pourquoi "L" est-il le suffixe préféré, pourquoi pas "I" par exemple? Y a-t-il une raison historique?

De plus, pourquoi R me permet-il de faire (avec des avertissements):

str(1.0L)
# int 1
# Warning message:
# integer literal 1.0L contains unnecessary decimal point 

Mais non..

str(1.1L)
# num 1.1
#Warning message:
#integer literal 1.1L contains decimal; using numeric value 

Je m'attends à ce que les deux renvoient une erreur.

30
Simon O'Hanlon

Pourquoi "L" est-il utilisé comme suffixe?

Je ne l'ai jamais vu écrit, mais je théorise en bref pour deux raisons:

  1. Parce que R gère les nombres complexes qui peuvent être spécifiés en utilisant le suffixe "i" Et ce serait trop similaire à "I"

  2. Parce que les entiers de R sont des entiers de 32 bits et "L" semble donc être un raccourci sensé pour faire référence à ce type de données.

La valeur qu'un entier long peut prendre dépend de la taille de Word. R ne prend pas en charge nativement les entiers avec une longueur de mot de 64 bits. Les entiers dans R ont une longueur de mot de 32 bits et sont signés et ont donc une plage de −2,147,483,648 À 2,147,483,647. Les valeurs plus importantes sont stockées sous la forme double.

Cette page wiki contient plus d'informations sur les types de données courants, leurs noms et plages conventionnels.

Et aussi de ?integer

Notez que les implémentations actuelles de R utilisent des entiers 32 bits pour les vecteurs entiers, donc la plage d'entiers représentables est limitée à environ +/- 2 * 10 ^ 9: les doubles peuvent contenir exactement des entiers beaucoup plus grands.


Pourquoi 1.0L et 1.1L renvoient-ils différents types?

La raison pour laquelle 1.0L Et 1.1L Renverra différents types de données est que le renvoi d'un entier pour 1.1 Entraînera une perte d'informations, tandis que pour 1.0 non (mais vous voudrez peut-être savoir que vous n'avez plus de numérique à virgule flottante). Enterré profondément avec l'analyseur lexical (/src/main/gram.c:4463-4485) Se trouve ce code (faisant partie de la fonction NumericValue()) qui crée en fait un type de données int à partir d'un double entrée suffixée par un ascii "L":

/* Make certain that things are okay. */
if(c == 'L') {
double a = R_atof(yytext);
int b = (int) a;
/* We are asked to create an integer via the L, so we check that the
   double and int values are the same. If not, this is a problem and we
   will not lose information and so use the numeric value.
*/
if(a != (double) b) {
    if(GenerateCode) {
    if(seendot == 1 && seenexp == 0)
        warning(_("integer literal %s contains decimal; using numeric value"), yytext);
    else {
        /* hide the L for the warning message */
        *(yyp-2) = '\0';
        warning(_("non-integer value %s qualified with L; using numeric value"), yytext);
        *(yyp-2) = (char)c;
    }
    }
    asNumeric = 1;
    seenexp = 1;
}
}
31
Simon O'Hanlon