Подсчет естественно начинается с нуля
Вот алгоритм подсчета яблок в корзине:
count := 0
for each apple in basket
count := count + 1
После выполнения вышесказанного, count
держится количество яблок. Это может быть ноль, потому что корзины могут быть пустыми.
Если вы не пользуетесь своей кредитной картой целый месяц, получаете ли вы счет в 1 доллар? Или 1 цент?
Когда вы сбрасываете счетчик пробега на одометре вашего автомобиля, он переходит на 0001 или 0000?
Массивы могут предоставлять несколько представлений одних и тех же данных.
Рассмотрим массив 32-битных структур d
, каждая из которых состоит из 16-битных слов w
. Каждое слово состоит из двух 8-битных байтов b
. При нулевой индексации наложение выглядит очень удобно:
d: | 0 | 1 |
w: | 0 | 1 | 2 | 3 |
b: |0|1|2|3|4|5|6|7|
32-битный объект d[1]
по адресу слова, w[2]
который легко вычисляется путем умножения индекса на 2, который является отношением размеров 32- и 16-битного объекта. Кроме того, в байтовой адресации это так b[4]
.
Это работает, потому что ноль равен нулю в каждой единице измерения: байт, слово, двойное слово и так далее.
Посмотрите на приведенную выше диаграмму: она очень похожа на линейку, где преобразование единиц интуитивно понятно.
С одним основанным индексированием это ломает:
d: | 1 | 2 |
w: | 1 | 2 | 3 | 4 |
b: |1|2|3|4|5|6|7|8|
Теперь мы не можем просто умножить d
индекс на 2, чтобы получить w
индекс, или на 4, чтобы получить b
индекс. Преобразование между единицами становится неуклюжим. Например, чтобы перейти от d[2]
к b[4]
, мы должны рассчитать ((2 - 1) * 4) + 1 = 5
.
Мы должны вычесть это надоедливое смещение 1 в d
единицах, затем выполнить масштабирование в естественной системе координат, основанной на нуле, и затем добавить обратно надоедливое 1 в b
единицах. Обратите внимание, что это не то же самое 1! Мы вычитаем ширину одного двойного слова, но затем добавляем ширину в один байт .
Преобразование между различными представлениями данных становится чем-то вроде преобразования Цельсия-Фаренгейта.
Те, кто говорят, что с одноосновными массивами легко иметь дело на уровне реализации, потому что есть только простое вычитание 1, обманывают себя и вас. Это верно только в том случае, если мы не делаем никаких вычислений масштабирования для различных типов данных. Такие вычисления выполняются в любой программе, которая имеет гибкий взгляд на данные (например, многомерный массив, также доступный как одномерный) или который управляет хранением: например, распределитель памяти, файловая система или библиотека буфера видеокадров.
Минимизация цифр
В любой базе, если мы хотим использовать наименьшее количество цифр для реализации диапазона значений, который является степенью основания, мы должны начинать с нуля. Например, в базовой десятке трех цифр достаточно, чтобы дать нам тысячу различных значений от 0 до 999. Если мы начнем с 1, мы переполнимся только одним значением и нам понадобятся четыре цифры.
Это важно в компьютерах, потому что количество цифр в двоичном коде переводится в аппаратные адресные строки. Например, чип ПЗУ с 256 словами в нем может быть адресован от 0 до 255, что требует 8 битов: от 00000000 до 11111111. Если он адресован от 1 до 256, то необходимы девять битов. Мы должны расточительно добавить еще одну трассировку адресов к плате или интегральной схеме. Так что на практике может случиться так, что 0 будет просто называться1 на уровне API программного обеспечения для доступа к этому чипу. Запрос слова 1 фактически поместил бы 00000000 на 8-битную адресную шину. В противном случае запрос на 1 будет преобразован в адрес 00000001, как и ожидалось, но запрос на 256 будет преобразован в неиспользуемый в противном случае 8-битный адрес 00000000, а не в 9-битный адрес 100000000. Оба этих кладбищ-кусочка действительно являются решениями в поиск проблемы и полностью исключаются путем последовательного использования от 0 до 255 на оборудовании, в программном обеспечении и во всех пользовательских интерфейсах и документации.
Единичные смещения в корне глупы
Рассмотрим, например, западную теорию музыки. У нас есть диатонические весы с семью нотами, но мы называем пространство, которое они покрывают октавой ! Инверсия интервалов затем следует правилу девяти : например, инверсия третьего является шестым (вычтите три из девяти). Таким образом, три разных числа находятся в игре для чего-то такого простого: семь (ноты в масштабе), восемь (октава) и девять (от вычитания до инвертирования).
Если бы семь нот составляли септав или гептав, а интервалы были равны нулю, то мы вычли бы из семи до инвертирования. Все основано на семи.
Кроме того, интервалы могут быть легко сложены. В нынешней системе, если мы прыгнем на пятую, а затем еще на четверть, а затем на треть, мы не можем просто добавить их. Результирующий интервал на два меньше. Это не двенадцатый, а фактически десятый! На каждом этапе мы должны вычитать один. Повышение на пятую, а затем на четвертую - не девятый, а только октава.
В разумно спроектированной музыкальной системе мы могли бы просто добавить интервалы для определения результирующих скачков. Последовательность нот, которая начинается и заканчивается на одной и той же ноте, будет иметь свойство, аналогичное закону напряжения вокруг цепи: все интервалы будут добавляться к нулю.
Теория музыки и письменность сильно устарели. Большая часть этого не изменилась, так как дни, когда сочинение было сделано ручками при свете свечи.
Системы на основе одного путают тех же людей, которые не могут обрабатывать массивы с нулями
Когда наступил 2000 год, многие были озадачены тем, что новое тысячелетие не началось. Те, кто указывал, что это не начнется до 2001 года, были расценены как партийные пижоны и паутины. В конце концов, вам 20, когда вам исполняется 20, верно? Не тогда, когда вам исполнится 21 год. Если вы думали, что тысячелетие началось 1 января 2000 года, то вы не имеете права жаловаться на массивы с нулями на любом языке программирования. Они работают так, как вам нравится. (Но, да, сторонниками смещений и массивов по принципу «один на один» являются dweebs и party-poopers. Столетия должны начаться в XX00 годах, а тысячелетия - в X000 лет.)
Календари тупые, но по крайней мере время суток начинается с нуля
Каждая новая минута на ваших часах начинается с: 00 секунд. Каждый новый час начинается с 00:00 минут и секунд. И, по крайней мере, на 24-часовых часах, день наступает, когда наступает полночь, и 11:59:59 увеличивается до 00:00:00.
Таким образом, если вы хотите вычислить секунды с полуночи для времени, подобного 13:53:04, вам просто нужно оценить 13 * 3600 + 53 * 60 + 4
. Нет безвкусных 1
дополнений или вычитаний.
Закрывающий спор о MIDI
Хорошо, что с музыкантами, даже якобы техническими?
MIDI! Он использует нумерацию с нуля для программ и каналов при фактическом представлении сообщений в проводном режиме, но устройство Gear отображает его как 1 на основе! Например, программы от 0 до 127 на большинстве передач называются от 1 до 128, но некоторые вызывают их от 0 до 127 или даже предоставляют пользователю выбор.
Программы с 71 по 80 считаются «банком» из десяти. Так сказано прямо на моей педали MIDI, например. Футсвитчи помечены цифрами от 1 до 10, и, если я нахожусь в седьмом банке, они выбирают программы с 71 по 80. Однако некоторые устройства или компьютерные программы отображают номера программ с 1 по 128 от 0 до 127 или даже дают пользователю выбор! Что хуже: системы на основе одного, или хаос, созданный с использованием как одного, так и нулевого уровня, основанного одновременно?
Номера каналов MIDI называются от 1 до 16, но представлены двоичными числами от 0 до 15. Как будто вне зависимости от представления на основе одного, некоторые устройства используют дисковый переключатель для настройки номера канала, и часто эти переключатели просто используют двоичный код, основанный на нуле. Так что если вы хотите канал 3, вы должны переключить его на 0010 (двоичный 2).