эквивалентные выражения

#math #bitwise-operators #modulo

#математика #побитовые операторы #modulo

Вопрос:

Я пытаюсь вычислить эквивалентные выражения следующих уравнений, используя побитовые операторы сложения и / или вычитания. Я знаю, что должен быть ответ (который, кроме того, обобщается для работы с любым модулем 2 ^ a-1, где a — степень 2), но по какой-то причине я не могу понять, какова связь.

Начальные выражения:

 x = n % (2^32-1);
c = (int)n / (2^32-1); // ints are 32-bit, but x, c, and n may have a greater number of bits
  

Моя процедура для первого выражения заключалась в том, чтобы взять значение по модулю 2 ^ 32, затем попытаться компенсировать разницу между двумя значениями по модулю. У меня возникли проблемы со второй частью.

 x = n amp; 0xFFFFFFFF   difference // how do I calculate difference?
  

Я знаю, что разница n%(2^32)-n%(2^32-1) является периодической (с периодом 2^32*(2^32-1) ), и есть «всплеск», начинающийся с кратных 2^32-1 и заканчивающийся на 2^32 . После каждого 2^32 кратного значения график разницы уменьшается на 1 (надеюсь, мои описания имеют смысл)

Аналогично, второе выражение может быть вычислено аналогичным образом:

 c = n >> 32   makeup // how do I calculate makeup?
  

Я думаю, что состав постоянно увеличивается на 1 при кратности 2^32-1 (и уменьшается на 1 при кратности 2^32 ), хотя у меня возникают проблемы с выражением этой идеи в терминах доступных операторов.

Ответ №1:

Вы можете использовать эти идентификаторы:

 n mod (x - 1) = (((n div x) mod (x - 1))   ((n mod x) mod (x - 1))) mod (x - 1)
n div (x - 1) = (n div x)   (((n div x)   (n mod x)) div (x - 1))
  

Первое происходит из (ab c) mod d = ((a mod d) (b mod d) (c mod d)) mod d .

Второе происходит от расширения n = ax b = a(x-1) a b при делении на x-1 .

Ответ №2:

Я думаю, что нашел ответ на свой вопрос:

Сначала вычислите c, затем используйте результаты для вычисления x. Предполагается, что сравнение возвращает 1 для true, 0 для false. Кроме того, все сдвиги являются логическими сдвигами.

 c = (n>>32)   ((t amp; 0xFFFFFFFF) >= (0xFFFFFFFF - (n>>32)))

x = (0xFFFFFFFE - (n amp; 0xFFFFFFFF) - ((c - (n>>32))<<32)-c) amp; 0xFFFFFFFF
  

редактировать: изменен x (нужно сохранить только младшие 32 бита, остальное — «мусор»)