Это не домашнее задание, просто то, о чем я подумал. Таким образом, прямое вычисление факториала не совсем быстро; мемоизация может помочь, но если результат должен уместиться в 32 или 64 бита, то факториал может работать только для входных данных с 0
по 12
и 20
соответственно. Итак... мы могли бы также использовать таблицу поиска:
n n!
0 1
1 1
2 2
3 6
4 24
5 120
6 720
7 5040
8 40320
9 362880
10 3628800
11 39916800
12 479001600
13 6227020800 2^32= 4294967296
14 87178291200
15 1.30767E+12
16 2.09228E+13
17 3.55687E+14
18 6.40237E+15
19 1.21645E+17
20 2.4329E+18
2^64= 1.84467E+19
Итак, предположим, я хочу иметь встроенную факториальную функцию C++, которая использует встроенный ассемблер, с ожидаемым в результате 32-битным или 64-битным целым числом без знака. Если вход отрицательный или достаточно велик, чтобы вызвать переполнение, выход должен быть равен 0. Как это можно сделать на ассемблере, чтобы он потреблял наименьшее количество циклов? Этот код будет работать на 64-битной архитектуре Intel/AMD. Если это возможно, я заинтересован в улучшении сценария наихудшего случая, поэтому 20!
не должно занимать намного больше времени, чем 0!
- надеюсь, есть подход бинарного поиска. Надеюсь, есть хитрый трюк для выполнения if (n == 0 || n == 1) { return 1; }
. Кроме того, если вывод должен быть 32-битным, то я думаю, что инструкции по сборке могут содержать в себе как код, так и данные. Мои познания в сборке слабые. Пожалуйста, дайте мне знать, если вопрос не имеет большого смысла.
Было бы неплохо иметь возможность использовать эту функцию в C++ — это делает проблему более реалистичной. Если, например, вызов функции обходится дорого, то попытка сэкономить 1-2 такта в теле сборки мало чем поможет.