100 факториал

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

sasadabest
Сообщения: 18
Зарегистрирован: 15 окт 2007, 01:44

17 окт 2007, 16:01

ок,поменял... проста когда вычисляешь факториал больших чисел ошибки незаметно.. всё равно сенкс :)
Serge_Bliznykov
Сообщения: 366
Зарегистрирован: 31 авг 2007, 03:06

17 окт 2007, 23:20

somewhere
тото, как я открыл файл Result.txt сразу увидел, что факториал не тот.... ;-)))))))))
sasadabest
Сообщения: 18
Зарегистрирован: 15 окт 2007, 01:44

31 окт 2007, 15:22

Somewhere очень благодарен за помощь но не мог бы ты в общих чертах пояснить прогу. Хотелось бы въехать в ход мыслей и сам процесс подсчёта факториала. Было бы очень любезно с твоей стороны. :)
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

31 окт 2007, 16:58

В общих чертах:

Используется всего одна операция: сложение. Рассмотрим факториал какого-нибудь числа и приведем все операции к одной. Например 5!. Сначала имеем единицу, теперь складываем ее саму с собой 2 раза, получили 2. Теперь складываем двойку саму с собой 3 раза, получили 6. Теперь складываем 6-ку саму с собой 4 раза, получили 24 и наконец 5 раз по 24 = 120. Вот и результат. Всего одна операция - сложение. Сейчас подробно объяснять времени нет, если не понятно, то лучше задавайте вопросы исходя из текста программы, а я поясню что к чему.
It's a long way to the top if you wanna rock'n'roll
sasadabest
Сообщения: 18
Зарегистрирован: 15 окт 2007, 01:44

01 ноя 2007, 16:06

именно из текста программы и есть вопросы... хорохо бы коментов добавить , если не трудно. Кстати спасиба за пояснение принципа работы програмы :)
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

02 ноя 2007, 09:25

Код: Выделить всё

.model tiny
.code
.386

jmp @start

Num1  db 199 dup (0), 1     ; Каждое число из 200 цифр, в этом храним 1
Num2  db 200 dup (0)         ; а этом 0
NFact dw 100                      ; Задаем, какой нужен N!
fName db 'Result.txt'           ; куда результат выводить
hFile dw 0	                         ; это хендл файла, задавать не надо, рассчитывается внутри проги

;//========================= Сложение
;// Input:
;// SI - Первое число
;// DI - Второе число
;//
;// Output:
;// SI - Результат сложения 

Addition proc near
pusha
mov cx, 199
add di, cx
add si, cx               ; начинаем с конца
xor ah, ah
	@add_1:
mov al, [si]            ; берем цифру из 1
add al, [di]             ; складываем с цифрой 2-го
daa                       ; корректируем в BCD
add al, ah              ; добавляем предыдущий разряд             
daa                       ; корректируем
mov ah, al            
shr ah, 4                ; старший разряд в старших 4 битах сохраняем в AH
and al,0Fh              ; оставляем младший
mov [si], al            ; и записываем
dec si                    ; переход к следущему
dec di
dec cx
jnz @add_1

popa
ret
Addition endp

;//================= Main code
	@start:
push cs
pop ds
push ds
pop es                    ; es = ds = cs
mov ah, 3Ch           ; Создаем файл
xor cx, cx
lea dx, Fname
int 21h
mov hFile, ax          ; для работы с ним используем хендл

mov bx, 2               ; начинаем считать с двойки
	@fact:
lea si, Num1
lea di, Num2
cld
mov cx, 100
rep movsw	              ; Num2 = Num1
lea si, Num1
lea di, Num2
mov cx, bx              ; кол-во необходимых сложений - 1
dec cx
	@fact1: 
call Addition             ; складываем
loop @fact1
inc bx                      ; переход к следущему множителю
cmp bx, NFact          ; пока не достигли нужного
jle @fact

lea si, Num1             ; подсчитали факториал, теперь переводим в  ASCII код
mov cx, 200
	@toascii:
add byte ptr [si], '0'        ; для этого добавим к каждой цифре код '0' или 30h
inc si
loop @toascii

lea si, Num1                  ; но у нас остались нули в начале
mov cx, 200
xor di, di                       ; и их сейчас будем убирать
	@k1:
cmp byte ptr [si], '0'      ; если не встретили 0, то выход из цикла
jnz @k2
inc di
inc si
loop @k1
	@k2:
mov ah, 40                   ; теперь в DI - кол-во пропущенных нулей
mov bx, hFile                ; а в SI - позиция в числе, с которой надо писать в файл
mov cx, 200
sub cx, di                     ; кол-во байт для записи = 200 - DI
mov dx, si
int 21h

mov ax, 4C00h             ; выходим
int 21h
end
It's a long way to the top if you wanna rock'n'roll
sasadabest
Сообщения: 18
Зарегистрирован: 15 окт 2007, 01:44

02 ноя 2007, 14:23

Щас буду сидеть разбираться... :) потом отпишусь если что ;)

ЗЫ:А тут нигде нелизя плюсик в репутацию поставить? :)
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

02 ноя 2007, 16:02

над сообщением пользователя в правом углу есть типа весы, нажав на них можно добавить отзыв.
It's a long way to the top if you wanna rock'n'roll
Voortex
Сообщения: 17
Зарегистрирован: 04 дек 2008, 07:56

08 дек 2008, 14:00

Извините, что поднимаю эту тему, просто мне выпала в задании честь найти факториал на ассемблере, здесь код который выложили, как раз почти подходит. Кстати он не работал у меня пока я вначале не поставил begin и в конце закрыл его. Здесь факториал дается в коде, а мне надо, чтобы самому ввести число и он его вычислил, еще самому задать имя файла, куда записать. И еще чтобы можно было найти факториал 1000. В этом я помойму разобрался, просто вверху поставил
Num1 db 999 dup (0), 1
Num2 db 1000 dup (0)
Немного с глюками выдает.
Ну и вот проблема в том что не могу сделать ввод числа и имени файла....
Если можете, помогите пожалуйста, буду очень-очень благодарен!
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

09 дек 2008, 14:50

1) Num2 - это массив из десятичных цифр факториала, мне лично не известно количество цифр в числе 1000! но без сомнений их больше 1000.
2) Для ввода с клавиатуры строки используйте функцию MS-DOS, для преобразования введеной строки в число - поищите в разделе "Ассемблер", в некоторых темах алгоритм имеется.
3) Ввод имени файла - также через функцию MS-DOS в массив fName
4) ВНИМАТЕЛЬНО следите за размерами массивов при считывании с клавиатуры, дабы не перекрыть другой участок памяти.
It's a long way to the top if you wanna rock'n'roll
Ответить