Подтвердить что ты не робот

Зачем R использовать суффикс L для обозначения целого числа?

В R мы все знаем, что это удобно для тех времен, которые мы хотим обеспечить, чтобы мы имели дело с целым числом, чтобы указать его с помощью суффикса "L" следующим образом:

1L
# [1] 1

Если мы явно не укажем R, мы хотим получить целое число, которое предположим, что мы использовали тип данных numeric...

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

Почему "L" является предпочтительным суффиксом, почему бы не "я", например? Есть ли историческая причина?

Кроме того, почему R позволяет мне делать (с предупреждениями):

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

Но не..

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

Я бы ожидал, что оба вернут ошибку.

4b9b3361

Ответ 1

Почему "L" используется как суффикс?

Я никогда не видел, чтобы это записано, но я кратко объясняю по двум причинам:

  • Beacuse R обрабатывает комплексные числа, которые могут быть указаны с помощью суффикс "i", и это будет слишком похоже на "i"

  • Поскольку целые числа R представляют собой 32-битные длинные целые числа, а "L", следовательно, представляется разумным сокращением для обращения к этому типу данных.

Значение, которое может принимать длинное целое число, зависит от размера слова. R не поддерживает целые числа со словом длиной 64 бит. Целые числа в R имеют длину слова 32 бита и подписаны и, следовательно, имеют диапазон от −2,147,483,648 до 2,147,483,647. Большие значения сохраняются как double.

Эта страница wiki содержит дополнительную информацию об общих типах данных, их обычных именах и диапазонах.

А также из ?integer

Обратите внимание, что в текущих реализациях R используются 32-битные целые числа для целых векторов, поэтому диапазон представляемых целых чисел ограничен примерно +/- 2 * 10 ^ 9: удваивает в точности целые числа большего размера.


Почему 1.0L и 1.1L возвращают разные типы?

Причина, по которой 1.0L и 1.1L будет возвращать разные типы данных, состоит в том, что возвращение целого числа для 1.1 приведет к потере информации, тогда как для 1.0 оно не будет (но вы можете захотеть узнать вас больше не имеют число с плавающей запятой). Погруженный глубоко с помощью лексического анализатора (/src/main/gram.c:4463-4485) - это код (часть функции NumericValue()), который фактически создает тип данных int из ввода double, который суффикс 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;
}
}