Быстро по модулю 3 или алгоритм подразделения?

С тех пор goto делает обоснование о процессе выполнения программы трудным <глоток> 1 (иначе. “spaghetti code”), goto вообще только используется для компенсации недостающих возможностей: использование goto может на самом деле быть приемлемым, но только если язык не предлагает более структурированный вариант для получения той же цели. Возьмите пример Сомнения:

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

Это - истинный †“, но только если язык не позволяет структурированную обработку исключений с кодом очистки (таким как RAII или finally), который делает то же задание лучше (как это особенно создается для того, чтобы сделать его), или когда будет серьезное основание не использовать структурированную обработку исключений (но у Вас никогда не будет этого случая кроме на очень низком уровне).

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

, Кроме которого, goto знак, что недостаточно мысли вошло в конкретную часть кода.

<час>

<глоток> 1 Современные языки, которые поддерживают goto реализация некоторые ограничения (например, goto может не вскочить или из функций), но проблема существенно остается тем же.

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

9
задан Anycorn 8 November 2009 в 17:59
поделиться

3 ответа

4% 3 == 1 , поэтому (4 ^ k * a + b)% 3 == (a + b)% 3 . Вы можете использовать этот факт для оценки x% 3 для 32-битного x:

x = (x >> 16) + (x & 0xffff);
x = (x >> 10) + (x & 0x3ff);
x = (x >> 6) + (x & 0x3f);
x = (x >> 4) + (x & 0xf);
x = (x >> 2) + (x & 0x3);
x = (x >> 2) + (x & 0x3);
x = (x >> 2) + (x & 0x3);
if (x == 3) x = 0;

(Непроверено - вам может потребоваться еще несколько сокращений.) Это быстрее, чем ваше оборудование может сделать x% 3? Если это так, то, вероятно, ненамного.

13
ответ дан 4 December 2019 в 12:19
поделиться

В этом элементе comp.compilers есть особая рекомендация по вычислению по модулю 3.

Альтернативой, особенно если максимальный размер дивиденда скромный, является умножение на величина, обратная 3, как значение с фиксированной запятой, с достаточной точностью для обработки делимого максимального размера, чтобы вычислить частное, а затем вычесть 3 * частное из делимого, чтобы получить остаток. Все эти умножения могут быть реализованы с помощью фиксированной последовательности сдвигов и сложений. Количество инструкций будет зависеть от битовой комбинации обратного. Это работает очень хорошо, когда максимальный дивиденд имеет скромный размер.

Что касается добавления цифр в число ... если вы хотите добавить десятичных цифр, вы собираетесь делать то, что количество на преобразование числа в десятичное, что предполагает деление где-то на 10. Если вы готовы довольствоваться сложением цифр в base2, вы можете сделать это с помощью простого сдвига вправо и добавления цикла. Для этого можно использовать различные хитрые приемы кусками по N бит, чтобы еще больше ускорить процесс.

Что касается добавления цифр в число ... если вы хотите добавить десятичных цифр, вы в конечном итоге сделаете то, что составляет преобразование числа в десятичное, что включает деление где-то на 10. Если вы готовы довольствоваться сложением цифр в base2, вы можете сделать это с помощью простого сдвига вправо и добавления цикла. Для этого можно использовать различные хитрые приемы кусками по N бит, чтобы еще больше ускорить процесс.

Что касается добавления цифр в число ... если вы хотите добавить десятичных цифр, вы в конечном итоге сделаете то, что составляет преобразование числа в десятичное, что включает деление где-то на 10. Если вы готовы довольствоваться сложением цифр в base2, вы можете сделать это с помощью простого сдвига вправо и добавления цикла. Для этого можно использовать различные хитрые приемы кусками по N бит, чтобы еще больше ускорить процесс.

4
ответ дан 4 December 2019 в 12:19
поделиться

Не уверен, что ответил на ваш первый вопрос, но для второго вы можете воспользоваться оператором % и целочисленным делением:

int num = 12345;
int sum = 0;
while (num) {
    sum += num % 10;
    num /= 10;
}

Это работает, потому что 12345% 10 = 5 , 12345/10 = 1234 и продолжайте до num == 0

0
ответ дан 4 December 2019 в 12:19
поделиться
Другие вопросы по тегам:

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