Существует ли способ реализовать эту очень простую булеву логику с помощью только математические операнды (такие как модификация)?

Я хочу уменьшить значение одним и если оно достигает нуля, установите его на максимальное значение. Есть ли способ сделать это через математику, не обращаясь к if (n-1 == 0) { n = max; }

Противоположный сценарий увеличивания значения одним и затем обнулением его, когда это больше, чем макс., может легко быть достигнут с помощью n = (n + 1) % (max + 1);. Кроме того, это еще лучше, так как можно увеличиться любой суммой (не всего один), и это все еще "перенесется" правильно.

Спасибо за ответы до сих пор. Чтобы быть ясным, я имел в виду без любой булевой логики (если/еще) или булевы операторы (!, &&, и т.д.) вообще. Мне было просто любопытно относительно того, как сделать это. Корректное отвечает ниже, действительно делают это более нечитабельным, пока комментарий предоставлен? Было бы необходимо использовать это для более общего случая для вычитания произвольного числа и ожидания, что корректные повторяются.

6
задан GreenieMeanie 17 February 2010 в 18:10
поделиться

11 ответов

n = max - ((max - n +1)%max)
6
ответ дан 9 December 2019 в 22:33
поделиться

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

5
ответ дан 9 December 2019 в 22:33
поделиться

Проблема в том, что оператор % в C возвращает отрицательный результат, когда сталкивается с отрицательным дивидендом. Часто это не то, что нужно.

Если вам нужна функция mod , которая будет выполнять -1 mod n == n-1 , то в C вы должны сделать следующее:

int mod(int a, int b)
{
    return (a%b + b) % b;
}

You затем можно выполнить

n=mod(n-1, max+1);

, чтобы уменьшить n и заставить его обернуться до max , когда n == 0 . Обратите внимание, что, как и в случае увеличения, это будет работать для произвольных размеров шага.

1
ответ дан 9 December 2019 в 22:33
поделиться

Почему бы просто не сравнить с 1?

if (n == 1) {n = max; }

-1
ответ дан 9 December 2019 в 22:33
поделиться

Возможно, есть лучший способ, но я думаю n = max - (max - n + 1)% (max + 1) работает. Я предполагаю, что вы хотите включить 0 на обоих концах, поскольку для вашего выражения приращения вы включаете 0.

0
ответ дан 9 December 2019 в 22:33
поделиться

sub foo
{
    my $params = $_[0];
    my %hash = %$params;
        foreach $keys (keys %hash)
        {
         print $keys;
        }
}

my $hash_ref = {name => 'Becky', age => 23};

foo($hash_ref);

Также хорошее введение о ссылках здесь .

-121--4349355-

Попробуйте pyqver: https://github.com/ghewgill/pyqver/

Предоставляет минимальную версию для данного скрипта python, анализируя используемые ключевые слова и модули.

Также можно скомпилировать локально python 2.2 и использовать virtualenv для создания среды python 2.2 с флагом --python.

-121--2470074-

Как насчет этого:
n =! n * max + (!! n) * n;

0
ответ дан 9 December 2019 в 22:33
поделиться

В JDK 1,0 действительно было необходимо иметь хотя бы один абстрактный метод в абстрактном классе. Это ограничение было снято в JDK 1.1 (1997? (Я старый)) и такие классы, добавленные в библиотеку Java, как java.awt.event.KeyAdapter .

В C++ необходима по крайней мере одна чистая виртуальная функция, чтобы сделать подкласс необходимым, и по крайней мере одна виртуальная функция, чтобы добавить RTTI в класс. Обычно имеет смысл использовать деструктор.

При переопределении неабстрактных методов рекомендуется использовать @ Override . Он не только сообщает читателю важную информацию о том, что пытается сделать код, но и обнаруживает распространенные ошибки, когда опечатки или неправильные типы параметров препятствуют переопределению.

-121--2190419-

Говоря с точки зрения ООП, я не думаю, что запись сохранит себя. Запись в базе данных - это просто данные, а сама база данных - это то, что делает с этими данными, будь то сохранение, загрузка или т.д. При этом я сделаю запись просто объектом, который содержит данные и создаст объект набора записей для взаимодействия с данными. В этот объект набора записей можно поместить список записей и соответствующим образом обновить его. Что-то вроде:

var recordset = function() {
    var me = this;
    var currentRecord = object.create("record");
    var recordList = object.create("recordList");
    me.save = function() {
            //Insert record.save code here
            recordList.refresh();
    };
};

Что-то отметить об этом коде. В этой настройке currentRecord и recordList не могут быть доступны вне функции, и поэтому у вас есть инкапсуляция, одна из отличительных черт OOP. Это происходит потому, что функция набора записей является замыканием, которое «закрывает» все переменные внутри, что означает, что каждая функция внутри имеет доступ к переменным в области набора записей.

Вы можете позволить внешнему миру получить доступ через функции get или set:

    me.getRecordList = function() {
        return recordList.getArray(); //Not generally a good idea to simply return your internal object
    };
-121--4067202-

Re: no booleans
Через магию целочисленного деления (C-стиль) мой предыдущий ответ можно записать как:
n = ((max-n )/max) * max + ((max + n-1 )/max) * n;

0
ответ дан 9 December 2019 в 22:33
поделиться

Просто чтобы спросить: почему вы хотите избежать логической операции?

Если вы хотите избежать использования условного кода в своем приложении, вы можете использовать логические выражения которые хранятся в логических значениях. Они будут сопоставлены с инструкциями SETcc на i386, и я предполагаю, что аналоговые инструкции существуют на других ISA.

В этом случае вы можете использовать логическое выражение и по-прежнему иметь не условный код, и вы можете использовать:

В предположении, что логический результат true равен порядковому номеру 1 (это случай в коде Delphi) и логическое значение false равно 0, вы можете написать

next := current - 1 + ( ( 1 + max ) and -Ord( current = 0 ) );

Не голосуйте против, потому что я дал ответ с помощью логических операций. Я просто хочу проверить, является ли это альтернативным решением основной проблемы.

Тем не менее: я думаю, что условный код намного удобнее читать.

0
ответ дан 9 December 2019 в 22:33
поделиться

На любом языке оценки логики короткого замыкания (большинство современных языков) вы можете сделать что-то вроде этого:

--n<=0 && n=max;

Вы можете получить волосатый глаз от некоторых ваших коллег, если ваша команда не привыкла использовать && в качестве оператора if-then.

Чтобы выполнить инкремент прямого цикла:

++n>max && n=1;

Эти примеры предполагают счетчик с 1-индексом, поскольку ваш вопрос, похоже, предполагает это. Эквиваленты с 0-индексом:

--n<0 && n=max-1;

++n>=max && n=0;

-1
ответ дан 9 December 2019 в 22:33
поделиться

На самом деле вы можете сделать также

n = (n - 1) + ((!(n - 1)) * max);
0
ответ дан 9 December 2019 в 22:33
поделиться

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

Если вы выберете конкретный язык, скорее всего, это возможно. Например, в C или C ++ вы можете сделать что-то вроде: n = (n-1) + ((n-1) == 0) * max;

Если вам интересно, как это работает: в C, сравнение ( == в данном случае) дает результат 0 для ложного и 1 для истинного. Итак, мы добавляем max * 0 when / if n-1! = 0 и max * 1 when / if n -1 == 0 .

1
ответ дан 9 December 2019 в 22:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: