Правильный способ для целочисленной обертки? - PullRequest
0 голосов
/ 13 ноября 2018

Каков был бы относительно лучший / более правильный способ гарантировать, что целочисленное значение всегда будет иметь значение от 0 до макс. 8 в цикле for? ( Я использую 32 итерации, как и пример здесь ) Я нашел три варианта (A, B и C)

Пример:

int x = 0;
const int max = 8; // EDIT: Always in the power of two.

for (int i = 0; i < 32; ++i)
{
    // EDIT: "x++;" usage was incorrect here.
    x = i;

//  x = x % max;  // A
//  x &= max - 1; // B
//  x &= ~max;    // C (EDIT: Incorrect, dont use...)

    std::cout << "x: " << x << std::endl;
}

Любые другие предложения?

РЕДАКТИРОВАТЬ: Производительность имеет решающее значение, нужно самое быстрое решение. Я видел использование « x & = ~ max » в некоторых сторонних кодах, критичных к производительности. Похоже, они обернулись, используя этот трюк. Это действительно или быстрее, чем другие решения?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

Если [0,8) действительны и макс гарантированно равен степени 2, x &= (max-1) работает и работает быстрее, чем первое.Не могу сказать о С.

0 голосов
/ 13 ноября 2018

Для int решения для битовой маски (x &= (max-1);) и по модулю (x %= max;) дают разную сборку, потому что они дают разные результаты для отрицательных значений. Хотя модульное решение легче читать, оно может работать медленнее, чем модульное. Обычно вы используете x %= max;, поскольку это точно соответствует тому, что вы хотите сделать, но если производительность критична, решение с битовой маской стоит рассмотреть.

Обратите внимание, что для unsigned int gcc компилирует оба решения, используя одну and инструкцию.

Годболт: https://godbolt.org/z/WAckr7

0 голосов
/ 13 ноября 2018

И B, и C действительны в данном конкретном случае, но работают только тогда, когда max - это степень в два раза. Если это не так, %= будет так же быстро, как и все остальное.

...