Одна функция для сложения / вычитания в «Арифметике часов» / конгруэнтной математике? - PullRequest
1 голос
/ 29 июня 2010

Я хочу "смешать" данные char * в этой форме:

source = (source + some_primary_number) % 256;

- строка 256 из-за того, что мне нужно сохранить диапазон char.

так что я могу выполнять «смешивать» и «размешивать» в 2 функциях - вышеописанная реализация предназначена для микширования, а для размешивания:

source  = source  - some_primary_number;
if ( source  < 0)
{
    source  = 256 + source 
}

Это работает, конечно. Но есть ли возможность выполнять смешивание и размешивание с одной и той же функцией?

Я помню кое-что нечеткое с конгруэнтной математикой ...

Можете ли вы помочь мне, пожалуйста? Спасибо!

Ответы [ 6 ]

2 голосов
/ 29 июня 2010

Я не совсем уверен, что вы это имеете в виду, но в целом в модульной арифметике вычитание определенного x - это та же операция, что и при добавлении m - x, где m - это модуль (здесь, 256).

Так, например, если ваше «микширование» добавляет 47 (мод 256), то «размешивание» добавляет 209 (мод 256), потому что 209 = 256 - 47.

1 голос
/ 29 июня 2010

Какой тип микширования вы ищете? Как вы планируете использовать смешивание / размешивание?

С чистой точки зрения, если микширование и несмешивание могут выполняться с одной и той же функцией и одним и тем же основным номером, то это означает, что каждый выходной номер связан с ровно одним входным номером.

Я могу думать о XOR с константой как об одном из примеров ее собственной обратной функции.

Линейный конгруэнтный генератор обычно требует другой функции не смешивания (обратной).

0 голосов
/ 30 июня 2010

Если вы объявляете source типом unsigned char, все должно работать. (Или uint8_t, если вы хотите более четко указать размер, но uint8_t не может существовать на платформах, где CHAR_BIT!=8 в любом случае.)

Один из возможных подводных камней - использование значения source+blah в выражении без предварительной записи его обратно в переменную типа unsigned char. В этом случае вполне может быть за пределами диапазона 0-255 из-за целочисленного продвижения. Если вам нужно это сделать, либо передайте результат сложения обратно unsigned char, либо замаскируйте его с помощью &0xff (или эквивалентно &255).

Кстати, не слушайте людей, которые говорят вам использовать% вместо &. Если вы не очень осторожны, чтобы убедиться, что выражения, которые вы используете с%, имеют тип unsigned int или больший тип без знака,% будет выполнять фактическую операцию деления / остатка, а не просто битовую маскировку. Люди все время путаются, думая, что компилятор будет оптимизировать% на степень 2, и не понимая, что оптимизация невозможна для подписанных типов.

0 голосов
/ 30 июня 2010

Похоже, вы хотите выполнить арифметику по модулю 256. C и C ++ поддерживают это с арифметикой без знака, поэтому, если вы приведете к unsigned char *, вы можете просто сделать очевидную математику.

0 голосов
/ 29 июня 2010

Я не уверен, что вы пытаетесь получить, но я думаю, что это может быть то, что вы хотите:

x = ( ((a + b) % M) + M ) % M;

Это вычислит общий остаток a + b по модулю M;это всегда приводит к числу [0..M).

. Он работает, сначала вычисляя (a + b) % M, затем + M на всякий случай, если он отрицательный, а затем % M снова.

0 голосов
/ 29 июня 2010

есть ли возможность выполнять смешивание и размешивание с одной и той же функцией?

int foo(int source, int some_primary_number)
{
    return (source + some_primary_number) & 255;
}

Для отмены микширования просто позвоните с отрицательным номером. Это то, что вы просили?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...