silently applies Two's complement
, да, на большинстве современных платформ это просто nop
, компилятор просто по-разному интерпретирует ваши данные.Так что это действительно трудно победить.
Для сравнения было бы неплохо, если бы вы предоставили некоторые критерии ...
Если я не ошибаюсь, 2 * abs(x) + signbit
можно сделать с помощьюциклический сдвиг влево битов.Так что, если на вашей платформе есть такая инструкция, это должно быть легко реализовано с помощью встроенного ассемблера и должно приводить только к одной инструкции в конце.будет работать только со знаком и значением представления отрицательных чисел.
Для дополнения до двух вам придется отрицать результат поворота, если вход был отрицательным.Что-то вроде
inline uint64_t rotateL(uint64_t x) {
asm ("rolq %0" : "=r" (x) : "r" (x));
return x;
}
inline uint64_t value(uint64_t x) {
uint64_t ret = rotateL(x);
return (ret % UINT64_C(2))
? -ret
: ret;
}
Я посмотрел на ассемблер, который он создал с помощью gcc.Выглядит неплохо, имеет всего 5 инструкций
rolq %rax
movq %rax, %rdx
negq %rdx
testb $1, %al
cmovne %rdx, %rax