В чем разница между `1L` и` 1`?


152

Я часто видел, как символ 1L(или 2L, 3Lи т. Д.) Появляется в коде R. Какая разница между 1Lа 1? 1==1Lоценивает до TRUE. Почему 1Lиспользуется в коде R?


18
Примечание: 1 == 1Lдает TRUE, но identical(1, 1L)дает FALSE.
CJB

2
Смотрите также Разъяснение L в R
Хенрик

Ответы:


129

Итак, @James и @Brian объяснили, что означает 3L. Но зачем тебе это?

В большинстве случаев это не имеет значения - но иногда вы можете использовать его, чтобы ваш код работал быстрее и занимал меньше памяти . Двойной ("числовой") вектор использует 8 байтов на элемент. Целочисленный вектор использует только 4 байта на элемент. Для больших векторов это меньше тратится впустую памяти и меньше тратится на процессор (поэтому обычно быстрее).

В основном это относится к работе с индексами. Вот пример, где добавление 1 к целочисленному вектору превращает его в двойной вектор:

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) 

... но также обратите внимание, что чрезмерная работа с целыми числами может быть опасной:

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

... и, как указал @Gavin, диапазон целых чисел составляет примерно от -2e9 до 2e9.

Однако следует обратить внимание на то, что это относится к текущей версии R (2.13). R может изменить это в какой-то момент (64-битные целые числа были бы хорошими, что могло бы разрешить векторы длины> 2e9). Чтобы быть в безопасности, вы должны использовать .Machine$integer.maxвсякий раз, когда вам нужно максимальное целочисленное значение (и сводить его к минимуму).


1
Я думаю, что требования к памяти R одинаковы, независимо от типа, по крайней мере, в соответствии с object.size. Для этого полезно перейти на код Fortran или C, который может потребовать данные определенного типа.
Джеймс

2
Нет, попробуй object.size(1:100)против object.size(1:100+0)400 байтов + некоторые издержки против 800 байтов + некоторые издержки. Я обновил пример выше.
Томми

2
Стоит упомянуть, что переполнение целых чисел связано с использованием 32-разрядных целых чисел со знаком, следовательно, ограничено до +/- 2 * 10 ^ 9, даже на 64-разрядном R ...
Гэвин Симпсон,

1
@ Зак это также намного короче набирать :-)
Гэвин Симпсон

1
@ Гэвин Симпсон, конечно. Я действительно думал о ситуации, когда вы создаете целый вектор, как c(1L, 2L, 3L, 4L,...100L)против as.integer(c(1, 2, 3, 4,...100)).
Зак

54

Из раздела Константы в определении R Язык :

Мы можем использовать суффикс 'L' для определения любого числа с целью сделать его явным целым числом. Таким образом, «0x10L» создает целочисленное значение 16 из шестнадцатеричного представления. Константа 1e3L дает 1000 как целое число, а не числовое значение и эквивалентно 1000L. (Обратите внимание, что «L» рассматривается как квалифицирующий термин 1e3, а не как 3.) Если мы квалифицируем значение с «L», которое не является целочисленным значением, например, 1e-3L, мы получаем предупреждение, и числовое значение равно создано. Предупреждение также создается, если в числе есть ненужная десятичная точка, например, 1.L.


47

L определяет целочисленный тип, а не двойной, как стандартный числовой класс.

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

2

Чтобы явно создать целочисленное значение для константы, вы можете вызвать функцию as.integer или, более просто, использовать суффикс «L».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.