Есть два разумных подхода.
Один из них ваш: возьмите младшие n битов y
, обнулите средние n
биты x и "или" вставьте их на место.
Другой способ состоит в том, чтобы построить ответ из трех частей: младшие биты или средние биты или старшие биты.
Я думаю, что мне действительно больше нравится ваша версия, потому что я уверен, что n
и p
с большей вероятностью будут константами времени компиляции, чем x
и y
. Таким образом, ваш ответ становится двумя маскирующими операциями с константами и одной "или"; Я сомневаюсь, что у тебя все получится лучше.
Я мог бы немного изменить его, чтобы было легче читать:
mask = (~0 << p | ~(~0 << (p-n+1)))
result = (mask & a) | (~mask & (y << (p-n+1)))
... но это та же скорость (действительно, код), что и у вас, когда mask
является константой, и, возможно, медленнее, если mask
является переменной.
Наконец, убедитесь, что у вас есть веская причина для беспокойства об этом. Чистый код - это хорошо, но для чего-то такого короткого, поместите его в хорошо документированную функцию, и это не имеет большого значения. Быстрый код - это хорошо, но не пытайтесь микрооптимизировать что-то подобное, пока ваш профилировщик не скажет вам об этом. (Современные процессоры делают это очень быстро; маловероятно, что производительность вашего приложения будет ограничена такого рода функциями. По крайней мере, это «невиновно, пока не доказана вина».)