GOOGLE ADS

Freitag, 22. April 2022

Warum sollte R das Suffix "L" verwenden, um eine Ganzzahl zu bezeichnen?

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 numericDatentyp 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,648bis 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.0Lund 1.1Lunterschiedliche Datentypen zurückgibt, liegt darin, dass die Rückgabe einer ganzen Zahl für 1.1zu einem Informationsverlust führt, während 1.0dies 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 intDatentyp aus einer doubleEingabe 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

    Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

    Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...