Яка різниця між `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
@Zach це також набагато коротше набрати :-)
Гевін Сімпсон

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.


46

L вказує цілий тип, а не подвійний, ніж стандартний числовий клас.

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

2

Щоб явно створити ціле значення для константи, ви можете викликати функцію as.integer або більш просто використовувати суфікс "L".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.