Код: Выделить всё
bool modulo(uint64_t value)
{
constexpr auto CONSTANT = 5;
return value % CONSTANT == 0;
}
Это приведет к следующей сборке для всех констант (изменение только магических чисел):
Код: Выделить всё
modulo(unsigned long): // example here for "CONSTANT==5"
movabs rax, -3689348814741910323
imul rax, rdi
movabs rcx, 3689348814741910324
cmp rax, rcx
setb al
ret
Я уже нашел способ вычислить вторую константу для сравнения, примерно на основе восторга хакеров и исходного кода libdivde:
Код: Выделить всё
struct DivMagic64 {
int64_t magic;
uint64_t cmpConst;
};
constexpr DivMagic64 computeDivMagic(uint64_t d) {
assert(d >= 1 && (d & 1)); // only works for odd divisors
const uint64_t cmpConstant = ~uint64_t(0) / d + 1;
int64_t magic = ???;
return { magic, cmpConstant };
}
Код: Выделить всё
movabs rax, -5570586920043653947 // ???
imul rax, rdi
movabs rcx, 7169352535448719 // correctly calculated in computeDivMagic
cmp rax, rcx
Подробнее здесь: https://stackoverflow.com/questions/798 ... odulo-oper
Мобильная версия