Индексирование массива по частному
В следующем коде i
всегда будет четным числом, поэтому частное i / 2
всегда должно быть целым числом. Должен ли я все еще использовать Math.floor(i / 2)
быть в безопасности? Я спрашиваю, потому что JavaScript обрабатывает все числа как числа с плавающей запятой, поэтому я обеспокоен ошибками округления.
for (var i = 0; i < data.length; i = i + 2) {
var name = names[i / 2];
...
}
3 ответа
Согласно спецификации языка JavaScript (ECMAScript ®), если
i <= Number.MAX_SAFE_INTEGER + 1
затем i
может быть точно представлен, и разделение должно работать нормально.
Значение
Number.MAX_SAFE_INTEGER
наибольшее целое число n, такое, что n и n + 1 оба точно представимы как числовое значение.Значение
Number.MAX_SAFE_INTEGER
составляет 9007199254740991 (2 53 -1).
Раздел 12.7.3.2 Применение оператора /
В остальных случаях, когда не участвуют ни бесконечность, ни ноль, ни NaN, частное вычисляется и округляется до ближайшего представимого значения с использованием округления IEEE 754-2008 до ближайшего, связанного с четным режимом. Если величина слишком велика для представления, операция переполняется; результат тогда - бесконечность соответствующего знака. Если величина слишком мала для представления, операция не выполняется, и результатом является ноль соответствующего знака. Язык ECMAScript требует поддержки постепенного снижения нагрузки, как определено IEEE 754-2008.
Нет, вы не должны использовать Math.floor()
в этой ситуации.
Так как i
всегда ровно, а также names[1.00]
эквивалентно names[1]
,
Чтобы проверить, попробуйте ниже в консоли javascript.
Длина массива будет 20, и первые 10 элементов массива будут напечатаны
var names = ["nums1", "nums2", "nums3","nums4", "nums5", "nums6","nums7",
"nums8", "nums9","nums10", "nums11","nums12", "nums13","nums14", "nums15",
"nums16","nums17", "nums18", "nums19","nums20"];
for (var i = 0; i < names.length; i = i + 2) {
console.log(names[i/2]);
}
Разделение четных целых чисел на 2 всегда возвращает целое число, пока оно не переполняется
Number.MAX_SAFE_INTEGER
после этого целые числа сохраняются со степенью двойки, поэтому они теряют точность.
Однако у массивов, которые больше этого размера, могут возникнуть проблемы с доступом к их элементам (так как индексы становятся неточными), максимальное количество элементов, которые вы можете вставить в массив, ограничено именно этим максимальным безопасным целым числом. Так что в основном ваш код всегда будет работать, если это не так, то это потому, что массив переполняется, а не потому, что индекс неверен. Тем не менее, я скорее рекомендую вам сделать:
var array = ["one", "two", "three","four", "five", "six","seven",
"eight", "nine","ten", "eleven","twelve", "thirteen","fourteen", "fifteen",
"sixteen","seventeen", "eighteen", "nineteen","twenty"];
for(var i=0,l=array.length/2;i<l;i++){
console.log(array[i]);
}
Как это экономит эти ненужные математические операции...