Значение модуля или остатка в% всегда совпадает с оператором минус 1 от этого значения?
Вот пример кода
int test = 1234;
int modValue, andValue;
modValue = test % -8;
andValue = test & 7;
printf("Mod Value = %d And Value = %d\n", modValue, andValue);
int counter = 0;
for(counter = 0; counter < 10000; counter++) {
modValue = counter % -8;
andValue = counter & 7;
if(modValue != andValue) {
printf("diff found at %d\n", counter);
}
}
Идеальная ссылка: http://ideone.com/g79yQm
Отрицательные числа дают разные результаты, вот и все, кроме того, что они всегда функционируют одинаково для всех положительных значений?
Даже для отрицательных чисел они кажутся смещенными только на 1 циклический раунд.
Те, кому интересно, похож на этот вопрос. Почему нужен оператор по модулю? вопрос, но я не вычитать 1.
При этом используются отрицательные значения, которые выше значения модуля, и да, работает только для положительных значений.
Я нашел это из декомпилятора IDA-PRO Hex-Ray, кажется, иногда генерирует модуль %
и другие времена AND
&
оператор для обоих идентичных исходников afaik в разных функциях. Я думаю, это от оптимизатора.
Поскольку этот проект, который я декомпилировал, не должен даже использовать отрицательные значения, мне интересно, каков был исходный исходный код, сомневаюсь, что кто-то использует модуль с отрицательными значениями, хотя и кажется странным.
Также используя And
как команда модуля, насколько я знаю, циклическая операция всегда использует модуль, но в этом случае человек должен использовать Val And 7
поскольку Val % 7
это совершенно другой результат.
Забыл сказать, оригинальный код, скорее всего, используется abs(Val) and 7
поскольку что-то с модулем с положительными значениями кажется неправильным, я не думаю, что кто-то будет использовать модуль с отрицательными значениями, это выглядит непривлекательным для глаз. Так что, думаю, это лучшее, что могло быть.
2 ответа
Оптимизация x % N
в x & (N-1)
работает только если N
это сила двух.
Вы также должны знать, что x
положительно, в противном случае есть небольшая разница между операцией битовой маски и операцией остатка. Операция битовой маски создает остаток для евклидова деления, который всегда положителен, тогда как %
производит остаток для деления С /
, который округляется до нуля и дает остаток, который иногда является отрицательным.
Знак результата %
зависят от машины для отрицательных операндов, то же самое относится к переполнению / недостаточному заполнению. /
по доверенности следует тем же правилам.