Pull to refresh

Comments 68

UFO just landed and posted this here
Хмм… Странно, я использовал 8-иричные константы (но не строковые, а просто в коде) в своей странице 404.
Только что проверил — в Хроме 26-м все по прежнему работает.

      for(bit=0;bit<16;bit++)
      {
        sum = ((0164624 >>> (((v1>>>bit)&7)<<1))&3)+ 
              ((0164624 >>> (((v2>>>bit)&5)<<1))&3)+//&5 because we skip middle cell
              ((0164624 >>> (((v3>>>bit)&7)<<1))&3);
          
        new_state |= ((0340 >>> ((sum<<1) | ((v2>>>(bit+1))&1)))&1)<<bit;
      }
Константы работали, работают и будут работать. Меняется поведение parseInt без второго аргумента.
Тогда «эпоха восьмеричных чисел с ведущим нулём» всё-таки не оканчивается :-)
Напомните, пожалуйста, а зачем вообще были нужны восьмиричные числа? Я не могу себе представить, когда они удобнее шестнадцатиричных. Разве что в байте шесть бит, а не восемь.
Исторически сложилось. В *nix файловые права удобно представлять, к примеру.
Несколько раз было полезно в математикоинформатических задачах в универе. Но это от лени и нежелания писать велосипеды
UFO just landed and posted this here
Именно почему?) Октет — от латинского «octo», что переводится как «восемь».
UFO just landed and posted this here
Прошу прощения, я вас неправильно понял.
UFO just landed and posted this here
Байт? Т.е., например, их килобайт (как одна из едниниц измерения информации) не равен нашему? Вот уж путаница.
UFO just landed and posted this here
Может, все-таки «слово»?
В прошлые времена понятие «байт» действительно колбасило, но сейчас то оно устоялось. А вот размер слова может быть любым, он диктуется архитектурой.
Архитектурой диктуются и байты, и слова. Байт — минимальный размер независимой ячейки памяти. Слово — размер регистров/ШД — может состоять из нескольких байт.
Байт — минимальный размер независимой ячейки памяти

Вообще-то память изначально имела организацию вида N * сколько-то битных слов.
Байтовая организация пошла скорее от 8 битных процессоров.
Например у CELL/SPE «минимальная независимая ячейка памяти» 128бит. Как её нарезать на байты — дело второстепенное.
Название «байт» (слово byte представляет собой сокращение словосочетания BinarY TErm — «двоичный терм») было впервые использовано в 1956 году В. Бухгольцем (англ. Werner Buchholz) при проектировании первого суперкомпьютера IBM 7030 (англ.) для пучка одновременно передаваемых в устройствах ввода-вывода шести битов.
Я в курсе. Как это связано с моим постом?
В упомянутом вами IBM 7030 огранизация памяти была такая:
«Main memory was 16K to 256K 64-bit binary words»
Это уточнение вашего поста. Байтовая организация памяти — да, заслуга 8-битных процессоров. Байтовая организация ввода/вывода — несколько ранее.
а причём тут вообще ввод-вывод?
При том, что ввод/вывод ровно такая же часть архитектуры, как и память.
И вышеприведенное определение байта вполне себе верное, если «ячейки памяти» (на памяти свет клином не сошелся) заменить на «единицы хранения/передачи информации», даже на той архитектуре, которая не предусматривает байтовой организации памяти.
Ну так вы посмотрите что я отквотил и на что отвечал.
Определение байта или ввод-вывод вообще ни коим образом не касаются моего ответа.

если «ячейки памяти» (на памяти свет клином не сошелся) заменить на «единицы хранения/передачи информации»,

Пользы от этого будет не больше, чем если бы слова «ячейка» заменить на «розовый», а «памяти» на «слоник».
Интересы: изобретать велосипеды, любительский троллинг

Нужно было раньше в ваш профиль заглянуть. Отвечу только — хорошо, используйте «розовых слоников» если так вам больше нравится.
Лучше используйте «килооктет» тогда.
Тут возможна некоторая путаница в терминах.
Например, стандарты языка Си оговаривают следующее:
В байте всегда 8 бит
В char может быть сколько угодно бит, задается константой CHAR_BIT.

Это чтобы не возникало «их килобайта — нашего килобайта».

Понятие «слово» тут тоже не совсем удачно, ведь слово — это разрядность регистров процессора и/или шины данных. И в наши дни это вряд ли 8 бит :)
стандарты языка Си оговаривают следующее:
A byte is composed of a contiguous sequence of bits, the number of which is implementationdefined.
ISO/IEC 9899:1999 §3.6

Стандарты надо изучать в первоисточнике ;-)
В Си байтов вообще нету. typedef unsigned char byte — это всё равно unsigned char.
Вопрос интересный применительно к измерению скоростей передачи данных. На сколько мне известно, передача одного байта полезной информации занимает десять бит из тех, которые в мегабитах, которыми измеряются скорости сетей. Разумеется это так не в любых сетях, а, возможно, сейчас уже и вовсе не так.
Это из-за кодирования 8B10B. Каждые 8 бит входного потока превращаются в 10 бит выходного, при этом для последовательностей длиннее 20 бит гарантируется что разность количества нулевых и единичных бит не превысит 2, и подряд могут следовать не более 5 одинаковых бит (т.е. запрещены последовательности 111111 и 000000). Снижает требования к линии связи, позволяет синхронизировать приемник по данным. Широко используются: SATA 1,2,3; PCIe 1,2; USB 3; DisplayPort; DVI/HDMI; SAS; 1G Ethernet; Firewire 800+; Fibre Channel; InfiniBand (SDR,DDR,QDR); Serial RapidIO.

Однако это не единственный вариант кодирования и продвинутые стандарты (10 GE, 100 GE, Thunderbolt, Infiniband FDR, EDR) переходят на 64b66b. PCIe 3 еще более продвинутый: 128b/130b.
Прочитал ваш комментарий — будто на Википедию сходил.
UFO just landed and posted this here
Чтобы третий из пунктов Ваших («при работе с кодировками») был более понятен читателю комментариев, можно привести небольшой пример, и приведу.

Так как в байте восемь битов, то байт записывается тремя восьмеричными цифрами, из которых левая (старшая) цифра описывает только два левых (старших) бита, так что может принимать только четыре значения (0, 1, 2, 3), а не все восемь.

Поэтому, если в некоторой кодировке именно два старших бита имеют особенное значение, то восьмеричная запись байтов позволяет на лету при чтении отличать их по первой же (левой) цифре.

Примером является популярнейшая кодировка UTF-8: если восьмеричная запись байта имеет вид «3xx» (где «xx» — любые две цифры), то это стартовый байт многобайтовой последовательности, описывающей один символ, а если «2xx», то это один из последующих байтов такой последовательности. Запись же «0xx» или «1xx», наоборот, указывает на однобайтовый символ UTF-8, то есть на один из первых 128 символов (нумерация которых в UTF-8 совпадает с ASCII).
Спасибо большое, теперь понятно.
Я как-то привык бинарные протоколы разбирать просто сдвигами и битовыми масками.
UFO just landed and posted this here
«Не зная про них, сдвиги и маски выдают ерунду»?

Сдвиги и маски не знают про big-endian и little-endian, и выдают ерунду?

Пожалуйста, следите за русским языком.
UFO just landed and posted this here
Вообще-то для JS не актуально — согласно спецификации все должно работать однообразно.
Проблемы с порядком есть только в ASM и C/C++ — где решается автоматически через макросы SHL SHR — вот там как раз и будем мистика :)
Сдвиги и маски не зависят от endianness, если вы правильно перевели, когда читали из буфера или записывали в него.
Взялось как не странно для удобства человека ;)
в те далекие времена когда для программиста была НУЖНА была информация о битах
в 2чной системе работать не очень удобно(слишком длинно) 0b1000111010001
в 8ричной же — компромис между легкостью восприятия человеком и использованием обычной записи 0-7
все цыфры кодируют 3 бита двоичного числа, и запомнить 8 комбинаций достаточно легко
как результат 0b1000111010001 -> 1 000 111 101 001 (bin) -> 10751 — легко делать в голове

в те времена у машины могла быть разрядность не кратная степени 2ки, например 18бит

16ричная систем менее удобна для ЧЕЛОВЕКА ;)
но она уже привычна
и удобна там где разрядность степени 2ки
ну и 16ричное число короче по записи
для 16бит максимальное число 0xFFFF == 0177777
в общем вытеснило оно в обычной жизни

хотя вопрос скорее привычки
на PDP архетектурах было принятов работать в 8ричной системе
на интелах обычно 16ричная
а на ZX-Spectrum были люди которые использовали 10чные числа, и их это устраивало… ;)
Шестнадцатиричная система сейчас удобна, т. к. в x86 и ARM байты — это октеты, а 8 делится на 4 без остатка, поэтому по количеству разрядов можно легко понять, сколько октетов потребуется для числа, просто взглянув на число: один октет — до 2 цифр, два — до 4, три — до 6, четыре — до 8.

А в восьмиричной системе один октет — от 0 до 0377, два — от 0400 до 0177777, три — от 020000 до 077777777, четыре — от 0100000000 до 037777777777.
Вот с 6 битами нормально, как выше было написано.
Подозреваю, что основная причина в том, что 8 меньше десяти, а 16 больше. С практической точки зрения это означает, что для ввода восьмиричного числа достаточно стандартной цифровой клавиатуры а-ля калькулятор, а для вывода опять же стандартного цифрового устройства вывода, например газоразрядного знакового индикатора.
Для parseInt можно указать систему счисления: parseInt(«042», 10) === 42
Это кстати очень рекомендуется почти всеми книгами по JS.
Подозреваю, проблема в том, что так практически никто не делает.
Один раз столкнулся с такой ошибкой, с тех пор взял за правило всегда указывать нужную систему счисления.
Ну вот давайте не будем придираться и сравнивать ToNumber и parseInt. Когда я пишу + перед строкой, которая представляет из себя упакованное в строку число с плавающей точкой, то я вполне адекватно полагаю, что на выходе получу float, аналогично с целыми. Когда я пишу + перед месевом из цифр и букв (42px), то я естественно ожидаю получить NaN. Это очевидно, естественно и просто — вот эти 3 составляющие являются ключевыми в любом API и ЯП. parseInt же, в свою очередь, имеет далеко не очевидное поведение.
месевом
месевом
месевом
[Staredad]
Адекватнее тот приём, который более адекватен задаче. Кто готов получить дробное число или NaN, тот да использует плюс перед строкою; кто желает отбросить дробную часть или получить ноль вместо NaN, тот да использует «|0» после строки.
Вполне логично. Непонятно, откуда исторически взялся этот дурацкий синтаксис с ведущим нулем, очевидно же что для восьмеричных нужно было делать префикс «o» (0o42) а для двоичных «b» (0b1010), было бы единообразие с шестнадцатеричными и не было бы глупых ошибок.
Исторически — из C, в который это попало из B, а в него — из BCPL (разве что префиксом восьмеричных констант была 8 — подчеркнутая 8): sundry.wikispaces.com/octal-zero-prefix и stackoverflow.com/a/11483339

Ранние версии C даже допускали восьмеричные константы 08 и 09 — www.coding-guidelines.com/cbook/cbook1_2.pdf стр 829

Еще в википедии есть примерно такое объяснение популярности восьмеричной системы, en.wikipedia.org/wiki/Octal#In_computers

Octal became widely used in computing when systems such as the PDP-8, ICL 1900 and IBM mainframes employed 12-bit, 24-bit or 36-bit words. Octal was an ideal abbreviation of binary for these machines because their word size is divisible by three (each octal digit represents three binary digits). So four, eight or twelve digits could concisely display an entire machine word. It also cut costs by allowing Nixie tubes, seven-segment displays, and calculators to be used for the operator consoles, where binary displays were too complex to use, decimal displays needed complex hardware to convert radices, and hexadecimal displays needed to display more numerals.
А автор префикса 0 — Ken Thompson. По крайней мере так утверждает Dennis Ritchie:

> I wonder if it's possible to add the reasons *why* B used a leading
> zero.
>
> Similarly, it looks like Thompson was first to use a leading zero in
> this way but there may be other languages that predated B that did the
> same. Perhaps those languages influenced B.
In the (original) BCPL manual we had at the time,
cm.bell-labs.com/cm/cs/who/dmr/bcpl.html
octal constants
were indicated in the typescript by an initial underlined 8. As we rendered
this in our in our compiler, octal numbers began with a #.

When Thompson did B, he chose to use a leading 0
instead, for reasons of his own.
Префикс то ладно… Если в исходном коде такое встречается, то это одно, но зачем parseInt его интерпретирует? Например atoi() всегда по base10 работает.
Некоторые компиляторы C для микроконтроллеров поддерживают запись 0b01010101. Удобно.
Да и С++11 теперь их косвенно поддерживает, через «пользовательские литералы».
С восьмеричными печально. Ну ладно си, исторически так сложилось, но непонятно, почему современные языки это тянут за собой?
Я в упор не понимаю, почему бы вообще всем языкам программирования в том или ином виде не поддерживать двоичную запись чисел. Это же основа основ.
А зачем всем языкам её поддерживать? Для чего нужны двоичные литералы? Для задания чисел они не удобны, для констант, используемых в битовых масках — тоже (проще написать, а, главное, прочитать «1 << 24», чем «0b1000000000000000000000000», или тем более, «1 << 24 | 1 <<16», чем «0b1000000010000000000000000», причем я даже не уверен, что правильно двоичное представление написал).
Для этого существует другое полезное расширение синтаксиса, до которого разработчики языков тоже не сразу доперли — подчеркивания в числах:
0b1000_0000__1000_0000__0000_0000
Это кстати полезно не только в двоичных числах, но и вообще в любых.
руби — поддерживает ;)
while a < 1_000_000_000_000 do_this_one_trillion_times()
Which is equivalent to:
while a < 1000000000000 do_this_one_trillion_times()
Как интересно. А кто еще поддерживает?
Хватит уже придираться. Лично мне даже нравится, что человек разбавляет технический текст художественными элементами, и читать приятнее, и видно, что автор подходит к делу с интересом.
Sign up to leave a comment.

Articles