In R wissen wir alle, dass es für die Zeiten, in denen wir sicherstellen möchten, dass wir es mit einer Ganzzahl zu tun haben, bequem ist, sie mit dem "L"
folgenden Suffix anzugeben:
1L
# [1] 1
Wenn wir R nicht explizit sagen, dass wir eine Ganzzahl wollen, wird davon ausgegangen, dass wir einen numeric
Datentyp verwenden wollten...
str( 1 * 1 )
# num 1
str( 1L * 1L )
# int 1
Warum ist „L" das bevorzugte Suffix, warum beispielsweise nicht „I"? Gibt es einen historischen Grund?
Warum erlaubt mir R außerdem (mit Warnungen):
str(1.0L)
# int 1
# Warning message:
# integer literal 1.0L contains unnecessary decimal point
Aber nicht..
str(1.1L)
# num 1.1
#Warning message:
#integer literal 1.1L contains decimal; using numeric value
Ich würde erwarten, dass beide entweder einen Fehler zurückgeben.
Lösung des Problems
Warum wird "L" als Suffix verwendet?
Ich habe es nie aufgeschrieben gesehen, aber ich theoretisiere kurz aus zwei Gründen:
Weil R komplexe Zahlen verarbeitet, die möglicherweise mit dem Suffix angegeben werden "i"
und dies zu ähnlich wäre"I"
Denn die Integer von R sind 32 Bit lange Integer und „L" erscheint daher als sinnvolle Abkürzung für diesen Datentyp.
Der Wert, den eine lange Ganzzahl annehmen kann, hängt von der Wortgröße ab. R unterstützt nativ keine ganzen Zahlen mit einer Wortlänge von 64 Bit. Ganzzahlen in R haben eine Wortlänge von 32 Bit und sind vorzeichenbehaftet und haben daher einen Wertebereich von −2,147,483,648
bis 2,147,483,647
. Größere Werte werden als gespeichert double
.
Diese Wiki-Seite enthält weitere Informationen zu gängigen Datentypen, ihren konventionellen Namen und Bereichen.
Und auch von?integer
Beachten Sie, dass aktuelle Implementierungen von R 32-Bit-Ganzzahlen für ganzzahlige Vektoren verwenden, sodass der Bereich darstellbarer Ganzzahlen auf etwa +/-2*10^9 beschränkt ist: Doubles können viel größere Ganzzahlen genau enthalten.
Warum geben 1.0L und 1.1L unterschiedliche Typen zurück?
Der Grund dafür, dass 1.0L
und 1.1L
unterschiedliche Datentypen zurückgibt, liegt darin, dass die Rückgabe einer ganzen Zahl für 1.1
zu einem Informationsverlust führt, während 1.0
dies nicht der Fall ist (aber Sie möchten vielleicht wissen, dass Sie keine Fließkommazahl mehr haben). Tief im lexikalischen Analysator ( /src/main/gram.c:4463-4485
) vergraben ist dieser Code (Teil der Funktion NumericValue()
), der tatsächlich einen int
Datentyp aus einer double
Eingabe erstellt, der ein ASCII angehängt ist "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;
}
}
Keine Kommentare:
Kommentar veröffentlichen