Без ветвления: (предполагается, что два целых числа дополняют)
#include <stdio.h>
int main(void)
{
printf("Enter 2 chars: ");
char a = getchar();
char b = getchar();
char c = a - b;
c = (c^-(c < 0)) + (c < 0);
printf("%d\n", c);
}
Разделить на части:
(c < 0)
дает 0
, когда c
положительно:c = (c^-0) + 0
~> c = c^0
... $ foo XOR 0 дает $ fooc = c
ничего не делать.(c < 0)
дает 1
, когда c
отрицательно:c = (c^-1) + 1
... -1
в двух дополнениях установлены все биты (~0
)c = (c^(~0)) + 1
... отрицательный c
в дополнительном коде XOR ~0
дает -c - 1
c = -c - 1 + 1
~> c = -c
gcc 8,3 -O3: (cl v15.9.0-pre.3.0 создает эквивалентную сборку)
mov edx, edi ; edx = c
shr edx, 31 ; right shift, keep only the sign bit (c < 0) [sign]
mov eax, edx ; eax = [sign]
neg eax ; eax = -[sign]
xor eax, edi ; eax = -[sign] xor c
add eax, edx ; eax += [sign]