Значение модуля или остатка в% всегда совпадает с оператором минус 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 положительно, в противном случае есть небольшая разница между операцией битовой маски и операцией остатка. Операция битовой маски создает остаток для евклидова деления, который всегда положителен, тогда как % производит остаток для деления С /, который округляется до нуля и дает остаток, который иногда является отрицательным.

Знак результата % зависят от машины для отрицательных операндов, то же самое относится к переполнению / недостаточному заполнению. / по доверенности следует тем же правилам.

Другие вопросы по тегам