Прежде чем мы начнем реализовывать факториал с использованием Python, давайте сначала обсудим, что подразумевает факториал числа.
Теоретически факториал числа определяется как произведение всех положительных целых чисел, меньших или равных числу. Конечно, n! представляет собой факториал целого числа n. В качестве примера рассмотрим факториал числа 6:
6! = 6 * 5 * 4 * 3 * 2 * 1
Чтобы определить факториал целого числа, можно использовать следующие методы:
- Использование цикла.
- Использование рекурсивного вызова функции.
- Использование предопределенной функции factorial() из математического модуля.
Использование цикла
Приведенный ниже код показывает, как можно вычислить факториал заданного числа с помощью цикла for в программировании на Python.
n=9 fact=1 for i in range(2,n+1): fact=fact*i print(«The factorial of «,n,» is: «,fact)
The factorial of 9 is: 362880
Использование вызова функции рекурсии
Точно так же мы можем вычислить факториал заданного числа с помощью рекурсивной функции. Посмотрим, как:
Пошаговое объяснение программы для вычисления факториала
n=9 def fact(n): if(n==1 or n==0): return 1 else: return n*fact(n-1) print(«The factorial of «,n,» is: «,fact(n))
The factorial of 9 is: 362880
Использование метода factorial() из математического модуля
Математический модуль обеспечивает простой способ вычисления факториала любого положительного целого числа.
Конечно, в модуле есть предопределенный метод factorial(), который принимает целое число в качестве аргумента и возвращает факториал числа. Давайте посмотрим, как мы можем использовать предопределенный метод и, следовательно, найти факториал. В приведенном ниже коде показано, как можно использовать метод factorial().
import math n=9 print(«The factorial of «,n,» is: «,math.factorial(n))
The factorial of 9 is: 362880
Кроме того, во всех вышеупомянутых методах мы использовали заранее определенное значение целого числа «n». Также возможно создание пользовательского ввода «n». Этого легко добиться, заменив строку n = 9 на:
n=int(input(«Enter the number for calculating factorial»))
Источник: pythonim.ru
Пишем самомодифицирующуюся программу вычисления факториала под x86
Самомодифицирующиеся программы воспринимаются как нечто магическое, но при этом они весьма просты, и чтобы это продемонстрировать, я напишу такую программу под x86 архитектуру в NASM.
Базовый факториал
Для начала нам понадобится обычная программа вычисления факториала.
factorial: push ebp mov ebx, eax factorial_start: sub ebx, 1 cmp ebx, 0 je factorial_end mul ebx jmp factorial_start factorial_end: pop ebp ret
Здесь все довольно просто.
Блок-схема программы для вычисления факториала
Самомодифицирующийся факториал
В алгоритме вычисления факториала есть два места, в которых изменение значения при выполнении имеет смысл: начальное значение и множитель.
Технические особенности
Во-первых, самомодифицирующиеся программы имеют свою специфику. По умолчанию nasm собирает программу без возможности ее дальнейшей самостоятельной модификации, потому что раздел .text из соображений безопасности отмечается как не перезаписываемый. Чтобы изменить флаги этого раздела для активации возможности записи потребуется задействовать objcopy и кастомную программу.
Мой скрипт для сборки этих программ лежит здесь.
Начальное значение
В исходном коде начальное число передается через регистр eax . Чтобы использовать для этого самомодифицирующийся код, первым делом потребуется, чтобы в начале функции присутствовала обнуляющая инструкция mov для eax .
_start: mov dword [factorial+2], 0x5 call factorial factorial: push ebp mov eax, 0
Как видите, для передачи начального значения программа изменяет инструкцию mov eax . Значение 0 этой инструкции на 2 байта смещается от начала метода factorial .
Множитель
factorial_start: ; multiply mov ebx, 0 mul ebx
Выше представлена заглушка, используемая для умножения. Далее нам нужна логика для установки mov ebx, 0 , его декрементирования и выхода из цикла.
Инициализация множителя
Для установки множителя берем ebx , где хранится его первое значение, и копируем это значение в mov eax, 0 в начало метода factorial_start .
factorial: . mov dword [factorial_start+1], ebx ; init decrementer
Декрементирование множителя
В стандартной программе логика будет такой:
- декрементировать множитель;
- если он окажется 0, выйти;
- перепрыгнуть назад.
Для этого необходимо получить его текущее значение, уменьшить это значение и скопировать обратно.
factorial_start: . ; decrement mov ebx, dword [factorial_start+1] sub ebx, 1 mov dword [factorial_start+1], ebx
Результат
Совмещая все это, получаем:
extern printf section .data format: db «num: %d»,10,0 section .text global _start _start: mov dword [factorial+2], 0x5 ; start number call factorial ; print result push eax push format call printf ; exit mov eax, 1 mov ebx, 0 int 80h factorial: push ebp mov eax, 0 mov ebx, eax sub ebx, 1 mov dword [factorial_start+1], ebx ; init decrementer mov ebx, 0 factorial_start: ; multiply mov ebx, 0 mul ebx ; decrement mov ebx, dword [factorial_start+1] sub ebx, 1 mov dword [factorial_start+1], ebx ; exit if at 0 ; could exit at 1, but then it doesn’t handle 0x2 cmp ebx, 0 je factorial_end ; loop back jmp factorial_start factorial_end: pop ebp ret
Заключение
Я нахожу самомодифицирующиеся программы довольно интересными – их код выглядит несколько иначе, немного беспорядочен и содержит пустые значения, но при этом продумывать для них логику очень увлекательно.
Применяются они в различных областях, в основном относящихся к обфускации – к примеру, при реализации защиты лицензий или вредоносного ПО. Я подумываю создать на этом принципе собственный упаковщик или, по меньшей мере, прикольный crackme.
Если вам интересно познакомиться с другими примерами самомодифицирующихся программ под x86, то милости прошу в мой репозиторий.
- Блог компании RUVDS.com
- Ненормальное программирование
- Assembler
Источник: habr.com
Факториал
Вычисление факториала на C++ можно провести с помощью циклов или рекурсии.
Стоит отметить, что так считают только факториалы небольших чисел. А для больших факториалов применяют более сложные подходы. Рассмотрим далее как расчёт факториалов с помощью циклов, так и с помощью рекурсии.
Вычисление факториала с помощью цикла for
Программа выглядит примерно так:
#include // подключаем cin/cout
#include // подключаем getch
for ( i = 1 ; i <= n ; i ++ ) <
res = res * i ;
В этой программе вначале подключаются заголовочные файлы iostream.h и conio.h. Затем объявляются переменные:
- n — целое число, факториал, которого будет вычисляться;
- i — счётчик;
- res — переменная для хранения текущего результата.
Затем осуществляется ввод с помощью команды cin, это можно сделать и по-другому, например, с помощью scanf.
Далее текущему результату присваивается значение 1. И в цикле проводится n умножений.
После этого подсчитанный факториал выводится на экран с помощью команды cout. И ожидается нажатие пользователем клавиши (команда getch).
Источник: proginfo.ru