если мы говорим о C и бла не находится под вашим контролем, то просто сделайте это:
if(blah) number += (1<<n);
В C нет логического значения, и его не нужно, false равно нулю иЗначение true не равно нулю, поэтому вы не можете предполагать, что не ноль равен 1, что вам нужно для вашего решения, и вы не можете предполагать, что установлен какой-либо конкретный бит в бла, например:
number += (blah&1)<<n;
Будетне обязательно работать, потому что 0x2 или 0x4 или что-либо ненулевое с нулевым битом считается истинным.Как правило, вы найдете 0xFFF ... FFFF (минус один или все), использованные как true, но вы не можете полагаться на типичные значения.
Теперь, если вы полностью контролируете значение в бла, и сохраняетеэто строго 0 к ложному и 1 к истинному, тогда вы могли бы делать то, о чем вы спрашивали:
number += blah<<n;
И избежать возможности ветвления, дополнительного заполнения строки кэша и т. д.
Вернемся к общему случаю, хотя, взяв это общее решение:
unsigned int fun ( int blah, unsigned int n, unsigned int number )
{
if(blah) number += (1<<n);
return(number);
}
И компиляцию для двух самых популярных / используемых платформ:
testl %edi, %edi
movl %edx, %eax
je .L2
movl $1, %edx
movl %esi, %ecx
sall %cl, %edx
addl %edx, %eax
.L2:
В приведенном выше примере используется условная ветвь.
В приведенном ниже примере используется условное выполнение, без ветвления, без очистки конвейера, детерминистически.
cmp r0,#0
movne r3,#1
addne r2,r2,r3,asl r1
mov r0,r2
bx lr
Могли бы сохранить инструкцию mov r0, r2, переставив аргументы в вызове функции, но это академично, вы не могли бы записать вызов функции на этом нормально.
РЕДАКТИРОВАТЬ:
Как предлагается:
unsigned int fun ( int blah, unsigned int n, unsigned int number )
{
number += ((blah!=0)&1)<<n;
return(number);
}
subs r0, r0, #0
movne r0, #1
add r0, r2, r0, asl r1
bx lr
Конечно дешевле, икод выглядит хорошо, но я не буду делать предположенияns что результат blah! = 0, который равен нулю или что бы компилятор определил как true, всегда имеет установленный lsbit.Этот бит не обязательно должен быть установлен компилятором для генерации рабочего кода.Возможно, стандарты диктуют конкретное значение для истины.путем перестановки параметров функции число if (blah) + = ... также приведет к трем одиночным инструкциям часов и не будет иметь допущений.
EDIT2:
Глядя на то, что я понимаюбыть стандартом C99:
Операторы == (равно) и! = (не равно) аналогичны операторам отношения, за исключением их более низкого приоритета.Каждый из операторов выдает 1, если указанное отношение истинно, и 0, если оно ложно.
Что объясняет, почему вышеописанное редактирование работает и почему вы получаете movne r0, # 1, а не какое-то другое случайноеnumber.
Постер задавал вопрос относительно C, но также отметил, что ADA был текущим языком, с точки зрения независимости от языка, вы не должны принимать "функции", такие как функция C выше, и использовать if (бла) число = число + (1 <