Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.05.2010, 15:27   #1
krast
Новичок
Джуниор
 
Регистрация: 25.05.2010
Сообщений: 1
По умолчанию Прога про двойной факториал!

Привет всем! У меня тут задача есть написать прогу для подсчета 1000!! (двойной факториал) Число нужно вводить через командную строку.

Двойной факториал, это например:

Если число четное, то двойной факториал будет: 2*4*6*8...
Если нечетное, то: 1*3*5*7...

Есть идея как сделать, чтоб было без проверки на четность и нечетность. Нужно взять введенное число и вычислять факториал с конца, например, если 10, то 10*8*6*4*2, т.е. loop до 2.

Вот нашел проги, вычисляющие простой факториал, но не могу в них изменить шаг на два, просерку условия (четное, нечетное) cmp думаю сделать смогу. Но даже по комментариям понять алгоритм пока не могу. Особенно большая проблема с вычислением умножения больших чисел, куда их вообще пихать! Стандартный оператор mul не прет! Собственно прошу помочь в написании данной проги. Заранее спасибо!

Цитата:
model tiny
.code
.186
nsize equ 3000
org 100h
;текстовый режим
begin: mov ax,3
int 10h
;выводим сообщение
mov ah,9
mov dx,offset dbEnter
int 21h
;начинаем ввод числа
xor si,si
mov bx,10
;считываем символ без эхо
InputNumber: xor ax,ax
int 16h
;проверяем нажатую клавишу
;это клавиша ввод
cmp al,13
jz InputStop
;это цифровая клавиша
cmp al,'0'
jb InputNumber
cmp al,'9'
ja InputNumber
;выводим цифру
push ax
int 29h
pop ax
;суммирем с ранее введенным числом
and ax,0fh
xchg si,ax
mul bx
add si,ax
;проверяем достигли ли предела вводимого числа
push si
and si,0f800h
pop si
;
jz InputNumber
;выводим сообщение об ошибке
xaxa: mov ah,9
mov dx,offset dbErrorInput
int 21h
jmp isStopWork
;начинаем посчет факториала
InputStop: mov dwNumber,si
;чистим буфер
mov cx,nSize
mov di,offset dwFactorial
xor ax,ax
cld
rep stosw
inc ax
mov [di],ax
;запоминаем адрес последней цифры
mov dwZeroPower,di
;востанавливаем максимальное число
mov cx,dwNumber
;настраиваемся для коррекции
isCorrection: mov dwNumber,cx
mov cx,nsize
mov ax,[di]
mov bx,10
;корректируем цифры
isLoopCorrection:
xor dx,dx
div bx
;остаток записываем
mov [di],dx
dec di
dec di
;суммируем с старшим разрядом
add ax,[di]
loop isLoopCorrection
;умножаем на текущий номер
mov bx,dwNumber
mov cx,nSize
;все цифры умножаем на текущее число
isLoopMultiplicate:
inc di
inc di
mov ax,[di]
mul bx
mov [di],ax
loop isLoopMultiplicate
;корректируем текущее число
mov cx,dwNumber
loop isCorrection
;создаем файл
mov ah,3ch
xor cx,cx
mov dx,offset dbFileName
int 21h
;ошибка создания файла
jc xaxa
;начинаем запись в файл
mov dwFileHndl,ax
mov si,offset dwFactorial
mov cx,nSize+1
xor di,di
;считываем число
isSave: lodsw
;Если ноль пропускаем установку флага
or ax,ax
jz isZero
mov di,-1
;проверяем флаг если ноль пропускаем запись
isZero: or di,di
jz noSave
push cx
;преобразовываем в символ
or ax,30h
mov [si-2],ax
;записываем символ в файл
mov ah,40h
mov bx,dwFileHndl
mov dx,si
dec dx
dec dx
mov cx,1
int 21h
pop cx
;все в цикле
noSave: loop isSave
;закрываем файл
mov ah,3eh
mov bx,dwFileHndl
int 21h
;нажимайте любую клавишу
isStopWork:
xor ax,ax
int 16h
ret
;
dwFileHNDL dw ?
dwZeroPower dw ?;не нужно
dwNumber dw ?
dbFileName db 'asCheck.txt',0
dbEnter db 13,10,'Enter Number:$'
dbErrorInput db 13,10,13,10,'Wronr input number$'
dwFactorial dw (nsize+2) dup(?)
end begin
krast вне форума Ответить с цитированием
Старый 28.05.2010, 12:39   #2
anyx
Форумчанин
 
Регистрация: 10.09.2009
Сообщений: 352
По умолчанию

А чем старый добрый рекурсивный метод не устраивает? Если Python (!) считает 1000! за доли секунды, то Асм не очень долго будет считать 1000!! Сложность в реализации длинной арифметики, хотя на Асме с умножением с переполнением это проще, чем на языке высокого уровня.
anyx вне форума Ответить с цитированием
Старый 28.05.2010, 13:03   #3
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

krast
Для начала напиши программу которая бы считала 4!!=2*4*6*8 и выводила бы на экран, получится пиши программу, которая считает 6!! и так далее пока не дойдешь до 100!! Все вычисления проверяй на калькуляторе, сможешь уловить закономерность -- значит напишешь и программу, которая считает 1000!! Затем напишешь программу которая получает число через командную строку. Удачи! Не боги горшки обжигают...
Mikl___ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Двойной счётчик Артур Иваныч Microsoft Office Excel 7 09.11.2009 07:30
Двойной запуск SONce Общие вопросы Delphi 4 15.04.2009 20:50
Прога про строки. Си stud007 Помощь студентам 11 01.03.2009 23:15
Двойной клик Алежа Общие вопросы .NET 3 16.11.2008 23:20