2010-06-29 3 views
1

Я хочу «смешивать» символ * данные в таком виде:Одна функция для сложения/вычитания в «Арифметике часов»/конгруэнтной математике?

source = (source + some_primary_number) % 256; 

--the 256 линии из-за мне нужно держать диапазон полукокса.

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

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

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

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

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

ответ

2

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

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

1

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

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

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

Linear congruent generator обычно требуется другая функция без смешивания (инверсная).

0

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

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

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

+0

Почему изменился модуль? Конечно, он будет действовать для любого модуля. –

+0

@Ben: Упс, смущенный '%' с '&' :) – fredoverflow

0

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

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

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

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

+2

Почему бы не просто '(a + b + M)% M'? – Boojum

0

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

0

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

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

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