А знали ли вы, что в C# сабж?
Ну, если быть точным, то UB.
И, чсх, это документировано.
Но кому придёт в голову читать документацию по оператору сдвига?!
Зачем разложили эти грабли?
Здравствуйте, pugv, Вы писали:
P>А знали ли вы, что в C# сабж? P>Ну, если быть точным, то UB. P>И, чсх, это документировано.
И где ты здесь UB увидел? Все там defined
If the type of x is int or uint, the shift count is defined by the low-order five bits of the right-hand operand. That is, the shift count is computed from count & 0x1F (or count & 0b_1_1111).
32 & 0b_1_1111 == 0 , поэтому для любого аргумента << 32 будет возвращать значение этого аргумента.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>If the type of x is int or uint, the shift count is defined by the low-order five bits
Только мелкомягкая недообразованная макака могла придумать такой маразм!! Причём тут вообще 5 бит??? Если я сказал СДВИГ, значит ДВИГАЙ, а не биты мне свои суй!
По адекватной логике, даже если я заказал сдвиг на 1000 бит, оно должно работать И ВОЗВРАЩАТЬ НОЛЬ! Любой другой ответ — маразм и бредятина.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>И где ты здесь UB увидел? Все там defined
The result of a shift operation is undefined if additive-expression is negative or if additive-expression is greater than or equal to the number of bits in the (promoted) shift-expression.
unsigned int int4 = int1 << 32; // C4293: '<<' : shift count negative or too big, undefined behavior
Здравствуйте, pugv, Вы писали:
P>А знали ли вы, что в C# сабж?
Это не только в C#.
P>Ну, если быть точным, то UB. P>И, чсх, это документировано.
Это не UB.
If the type of x is int or uint, the shift count is defined by the low-order five bits of the right-hand operand. That is, the shift count is computed from count & 0x1F (or count & 0b_1_1111)
Вообще-то, так работает процессор, что x86-64, что ARMы, и отражено в доках по архитектуре процессоров — значащие биты только первые 5 (31 бит влево/вправо можно сдвинуть). Вот, тут можешь посмотреть: Sharplab
В доках C# отразили только то, что по спекам делает процессор
SAL/SAR/SHL/SHR (x86)
The destination operand can be a register or a memory location. The count operand can be an immediate value or register CL. The count is masked to 5 bits, which limits the count range to 0 to 31.
PS. К тому же смысла сдвигать больше, чем на 31 бит все равно нет. А если уж так сильно хочется в результате получить ноль, то для этого есть куча другая способов добиться этого.
Здравствуйте, rameel, Вы писали:
R> Вообще-то, так работает процессор, что x86-64, что ARMы, и отражено в доках по архитектуре процессоров — значащие биты только первые 5 (31 бит влево/вправо можно сдвинуть).
Вот за это спасибо, никогда не задумывался.
R> PS. К тому же смысла сдвигать больше, чем на 31 бит все равно нет.
Да понятно, что нет. Напоролся при проверке по CIDR 0.0.0.0/0. Пришлось отдельное условие поставить на длину префикса подсети 0.
Здравствуйте, pugv, Вы писали:
НС>>А зачем?
P>Ну хотя бы, что бы не обрабатывать этот случай отдельно.
А его скорее всего и не обрабатывают. В ранних х86 процессорах сдвиг скорее всего бывл реализован тривиальным образом сдвиговым регистром, и его счетчик просто имел 4 разряда.
Здравствуйте, rameel, Вы писали:
R>Вообще-то, так работает процессор, что x86-64, что ARMы, и отражено в доках по архитектуре процессоров — значащие биты только первые 5
А каким боком "что делает процессор" относится к языку?!! Ты ещё скажи, что ЦПУ не умеет ООП и поэтому его не существует!
R>PS. К тому же смысла сдвигать больше, чем на 31 бит все равно нет
Господи, ещё один с "мелкомягкостью головного мозга".... То есть "всё, что не нужно инженерам микрософта — не нужно никому!" — я так понимаю логику??
Дело не в том, ЧТО ты получишь в результате, а в принципиальном подходе к сдвигу: ты не имеешь права "подгонять операцию под результат", сокращая число сдвигов! Клиент заказал дичь — значит надо выполнять дичь. Если клиент заказал умножение на ноль миллион раз — бери и умножай, ТАКОВ ПУТЬ. Для этого и существует понятие "машина", что она делает РОВНО ТО, ЧТО ПРИКАЗАЛИ. Любая отсебятина, "оптимизация" и прочие ведут к таким вот тупым результатам — сдвинул число влево, а оно НЕ НОЛЬ!! Это в какой вообще вселенной??
Здравствуйте, Kolesiki, Вы писали:
K> Господи, ещё один с "мелкомягкостью головного мозга".... То есть "всё, что не нужно инженерам микрософта — не нужно никому!" — я так понимаю логику??
При чем тут инженеры микрософта? Так ведет себя процессор.
Здравствуйте, Kolesiki, Вы писали:
K>А каким боком "что делает процессор" относится к языку?!!
Так язык — это всего лишь способ объяснить процессору что делать, но чуть более человекопонятно. Этот оператор язык всего-то компилирует в инструкцию SHL. Тут как раз всё ясно. Просто вот впервые в жизни столкнулся, хоть сам с ассемблера начинал.
Спасибо rameel и Смотрящему за разъяснения, век живи — век учись.
Здравствуйте, pugv, Вы писали:
P>А что там переполнится? Что мешает сдвинуть на всю длину типа, получив 0?
Производительность. В языке зашиты процессорная логика. Если она будет отличаться от процессорной ее придется эмулировать, что будет выливаться в тормоза при исполнении и ты уже не сможешь применять эффективные алгоритмы из С/С++. По тем же причинам в Шарпе типы данных имеют фиксированный размер, а не безразмерные как в разных тормозных скриптах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.