OriginalGriff
ОК: x-это (предположительно) целое число, что означает, что это набор (скажем) 32 битов, составляющих число: самый правый бит является наименее значимым, а самый левый-наиболее значимым, и они нумеруются от (обычно) бита 0 до бита 31, где индекс указывает степень двойки, которую содержит бит. Если вы притворяетесь, что целое число имеет четыре бита (чтобы упростить ввод):
Bit 0 == 2<sup>0</sup> == zero or one
Bit 1 == 2<sup>1</sup> == zero or two
Bit 2 == 2<sup>2</sup> == zero or four
Bit 3 == 2<sup>3</sup> == zero or eight.
И вы можете составить весь диапазон значений, которые может содержать (четырехразрядное) число, сложив вместе степени двух:
Value B3 B2 B1 B0
0 0 0 0 0
1 0 0 0 1
2 0 0 1 0
3 0 0 1 1
4 0 1 0 0
5 0 1 0 1
6 0 1 1 0
7 0 1 1 1
8 1 0 0 0
9 1 0 0 1
10 1 0 1 0
11 1 0 1 1
12 1 1 0 0
13 1 1 0 1
14 1 1 1 0
15 1 1 1 1
32-битные числа работают точно так же, но с огромным диапазоном значений!
Вопрос состоит в том, чтобы принять целочисленное значение, содержащее существующие биты, использовать целое число, которое говорит вам, с какого битового индекса начинать, с какого числа битов играть и со второго значения получать "новые" биты.
Таким образом, если N равно 6, вы хотите, чтобы правый 6 бит из y: б31, в30, в29, б28, b27, в26
и если p равно 2, вы хотите удалить шесть битов x, начиная с b2: b8, b7, b6, b5, b4, b3, b2 и заменить их битами, которые вы удалили из y.
Это кажется сложным, но это не так, не правда. Посмотрите на оператор AND "&", оператор OR " | "и операторы shift" и " и " - это все, что вам для этого нужно, в значительной степени.
the_beginner
хорошо, извините, позвольте мне разбить его:
1. Возьмите n самых правых битов Y и поместите их в точку P.
а) ~0< & lt;n - - - & gt; Чтобы сделать все биты 1, кроме самых правых N битов
b) ~(~0< & lt; n) -- & gt; получить его обратно
c) y & ~(~0 & lt; & lt; n) - - - & gt; сделайте все биты, кроме самых правых n битов, равными 0
d) (y & ~(~0<<n)) << (p-1) --> переместить n крайних правых битов Y в положение P
2. Теперь нужно сделать n битов x из позиции P в 0
a. те же шаги a-b от 1
b. ~((~(~0< & lt; n)) << (p-1))- - - > сделайте n битов из позиции P равными 0, а остальные будут равны 1.
c. x & ~((~(~0 & lt; & lt; n)) << (p-1)) --> сделайте n битов из позиции P как 0 в x.
3. Наконец, " или " между конечными результатами шага 1 и 2. чтобы получить желаемый результат.
(x & ~((~(~0 & lt; & lt; n)) << (p-1)) | ((y & ~(~0< & lt; n)) << (p-1))
OriginalGriff
Это не то, что я имел в виду: если вам нужно использовать в десять раз больше текста, чтобы объяснить одну строку кода (а вы это делаете: 640 символов объяснения против 54 символов кода), то ваш код непроницаем и, вероятно, должен быть переработан, чтобы сделать его ремонтопригодным.
Не беспокойтесь о плотности кода: компиляторы-лучшие оптимизаторы, чем большинство разработчиков, а ясность и понятность гораздо важнее краткости! :смеяться:
Да, вы могли бы включить эти удобочитаемые инструкции в качестве комментариев, но самодокументирующий код - лучшее решение, потому что у него гораздо больше шансов быть правым, комментарии часто не обновляются, когда код обновляется, и это делает их ненадежными.
Вместо этого делайте это поэтапно: извлекайте и "нормализуйте" биты. Затем удалите ненужные данные. Наконец, объедините их, чтобы получить результат. Использование удобочитаемых имен переменных для всех промежуточных этапов.
Да, это больше печатает, но это экономит вам огромное количество работы позже, когда вам нужно внести изменения - и одно из неписаных правил вычислений - "ничто не остается неизменным"; изменения происходят все время. Таким образом, написание кода, с которым трудно работать, усложняет вашу собственную жизнь на следующей неделе или в следующем месяце!