2015-06-16 7 views
1

У меня есть семафорная переменная с 5 состояниями.Как инвертировать эту формулу с оператором%

можно увеличить с помощью этого состояния Cicle

X = (X + 1) % 5 

Для Х = {0, 1, 2, 3, 4} порождают {1, 2, 3, 4, 0}.

Но если я попытаюсь пойти в другом направлении, уменьшая состояние, не приносит правильный результат.

X = (X - 1) % 5 

Для Х = {0, 1, 2, 3, 4} порождают {-1, 0, 1, 2, 3} InstEd из {4, 0, 1, 2, 3}

Например, в Excel, если вы пытаетесь =MOD(-1;5) вы получаете 4.

+1

В C# '%' возвращает остаток, а не модуль, поэтому я думаю, что всегда буду положительным. – Matt

+1

@Matt: остальная часть отрицательного аргумента по-прежнему отрицательна. – joe

+0

@Matt MOD в excel - это остаток, http://tipsforspreadsheets.com/microsoft_excel_2003_function_0019.html –

ответ

6

Вместо

X = (X - 1) % 5 

использование

X = (X + 4) % 5 

который является сокращенной формой

X = (X - 1 + 5) % 5 

или вообще

X = (X - 1 + n) % n 

Это гарантирует, что аргумент в () всегда положителен - поэтому остаток деления остается также положительным.

+0

То есть, странно, как Excel может обрабатывать отрицательные числа, но C# doesnt. –

+0

Ну, мой опыт в том, что Excel делает много неожиданных вещей ... – joe

+0

Идеальная формула будет X = (X - 1 + an)% n, где a - постоянное целое число, чтобы гарантировать, что конечный результат всегда является положительным модулем вычисления постсочетания, если у нас есть одно из числа as -15, тогда нам нужно кратное n, которое равно 5 для обеспечения положительного результата –

0

Проблема связана с тем, что вместо оператора модуля используется C# supports remainder operator.

Если ваш x всегда находится в диапазоне между 0 и n-1, тогда других простых решений достаточно. Если вам нужен метод, который работает для любого x, тогда вам потребуется нечто более сложное.

static int modulus(int x, int n) 
{ 
    return ((x % n) + n) % n; 
} 

Первая операция Остаток преобразует значение в диапазоне -n+1 ... n-1. Как только мы добавим n, мы получим всегда положительное значение. Затем конечная операция остатка дает ожидаемый результат.

+0

C# * не имеет оператора модуля *. Он имеет оператор * остатка *, но не модуль * модуля. Вы можете создать функцию, которая выполняет модуль, возможно, используя оператор остатка для его реализации, как вы это делали. (Вы также можете реализовать обратное, если вам это нужно.) Также обратите внимание, что внутренний '% n' совершенно лишний. – Servy

+0

@Servy Вы правы. Я исправил свой ответ. Спасибо. Кстати, внутренний '% n' не лишний, если мы хотим правильно рассчитать модуль любого отрицательного числа. Если мы имеем только '(x + n)% n', и мы имеем' x = -8' и 'n = 3', тогда' (-8 + 3)% 3 = (-5)% 3 = -2' и это не правильный результат. Предлагаемое выражение дает правильный результат '1'. – dlask

Смежные вопросы