bool isDiv3(unsigned int n)
{
unsigned int n_div_3 =
n * (unsigned int) 0xaaaaaaab;
return (n_div_3 < 0x55555556);//<=>n_div_3 <= 0x55555555
/*
because 3 * 0xaaaaaaab == 0x200000001 and
(uint32_t) 0x200000001 == 1
*/
}
bool isDiv5(unsigned int n)
{
unsigned int n_div_5 =
i * (unsigned int) 0xcccccccd;
return (n_div_5 < 0x33333334);//<=>n_div_5 <= 0x33333333
/*
because 5 * 0xcccccccd == 0x4 0000 0001 and
(uint32_t) 0x400000001 == 1
*/
}
Следуя тому же правилу, чтобы получить результат теста делимости на 'n', мы можем: умножить число на 0x1 0000 0000 - (1 / n) * 0xFFFFFFFF сравнить с (1 / n) * 0xFFFFFFFF
Аналог состоит в том, что для некоторых значений тест не сможет вернуть правильный результат для всех 32-битных чисел, которые вы хотите проверить, например, с делением на 7:
мы получили 0x100000000- (1 / n) * 0xFFFFFFFF = 0xDB6DB6DC и 7 * 0xDB6DB6DC = 0x6 0000 0004, мы протестируем только одну четвертую значений, но мы, безусловно, можем избежать этого с помощью вычитаний.
Другие примеры:
11 * 0xE8BA2E8C = A0000 0004, четверть значений
17 * 0xF0F0F0F1 = 10 0000 0000 1 по сравнению с 0xF0F0F0F Каждые значения!
И т.д., мы можем дажепроверить все числа, комбинируя между ними натуральные числа.