Частенько в руководствах и документации можно встретить термины big-endian и little-endian - да хотя бы в предыдущей записи про кодировки. Но что они вообще значат? На самом деле, всё довольно просто - это буквально война тупоконечников и остроконечников (я серьёзно).
Когда-то давно Джонатан Свифт написал роман "Путешествия Гулливера" - помните такой? Там была история, что, дескать, изначально варёные яйца лилипуты разбивали с тупого конца, но потом один из императоров умудрился себе порезать руку за завтраком, очищая яичко, после чего был издан указ: разбивать яйца только с острого конца, иначе будут применяться санкции.
Это привело к кровавым бунтам, тысячи человек пошли на казнь, так как, следуя заветам предков, всё равно разбивали яйца с тупого конца. По этой теме писались книги (хотя тупоконечную литературу запрещали), устраивались диспуты, и так далее, хотя в главном трактате некоего пророка было написано просто "разбивайте так, как вам больше нравится". Скажем прямо, в реальной жизни подобный идиотизм тоже встречается частенько. Это, конечно, едкая сатира, но она напрямую связана с нашим вопросом.
В оригинале "тупоконечники" - это big endians, а другая сторона - little endians. Отсюда и пошли эти термины - впервые в далёком 80-м году их употребил Дэнни Коэн, один из участников проекта ARPANet. Это была во многом шутка, но в итоге словечки прижились.
Предположим, у нас есть шестнадцатеричное число
0x12345678, и оно размещается в памяти, начиная с адреса 0x100 (про организацию память можно глянуть стрим https://youtube.com/live/1B6lBJUQ5q8?feature=share). Каждая двойка шестнадцатеричных чисел (12, 34 и тд) занимает по 8 бит (потому что каждое число hex требует 4 бит, 0x0 = 0b0000, 0xf = 0b1111).Следовательно, на всё это число потребуется 4 байта или 32 бита (это называется "слово", "word"). Если принять, что каждый адрес в памяти указывает на 8 бит информации, то наше число займёт адреса с
0x100 по 0x103. Но вопрос в том, как их там разместить: справа налево или слева направо?Можно сделать так:
100 101 102 103
12 34 56 78
но можно сделать и так:
100 101 102 103
78 56 34 12
То есть сначала может идти "самая значимая" пара (это
0x12), а может, наоборот, наименее значимая (0x78). Казалось бы, выбор очевиден, но можно вспомнить хотя бы о том, что некоторые народы читают справа налево, а кто-то вообще пишет столбиком. Так что, на самом деле, всё не так однозначно™.Поэтому подход, когда наиболее значимый байт идёт на первой позиции, называется "big endian" или BE (большинству из нас это куда привычнее), а "little endian" или LE - это когда сначала идёт наименее значимый байт. В разных машинах может задействоваться один из двух подходов, к примеру, многие устройства (но не все) от Oracle используют режим big endian. Впрочем, есть чипы вида bi-endian, которые умеют работать в обоих режимах.
Кроме того, многое зависит от самой операционной системы. Так, Android и iOS используют именно little-endian, с Windows в целом аналогичная история. В сетевых же протоколах, напротив, используется вариант big endian (принятую по сети информацию может потребоваться переставить обратно в вариант little endian, в зависимости от машины).
Дело же в том, что с технической точки зрения нет особенной разницы, какой вариант представления использовать, равно как и нет разницы, с какой стороны разбивать яйцо. Для обычных программистов знать, какой режим использует ОС, особенно не нужно, потому что это должны учитывать компиляторы.
Однако этот термин может встречаться в других местах - например, в документации Solidity и Ethereum, где рассказывается о хранении данных в слотах (к примеру, uint хранится в виде big endian, равно как и селектор функции в calldata).
Интересно, что сказал бы по этому поводу Свифт...