Индексирование массива по частному

В следующем коде 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]);
    }

Как это экономит эти ненужные математические операции...

Другие вопросы по тегам