Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Чемпионы рейтинга экспертов в этой рассылке Номер выпуска: | 1349 | Дата выхода: | 01.06.2010, 00:30 | Администратор рассылки: | Лысков Игорь Витальевич, Модератор | Подписчиков / экспертов: | 261 / 63 | Вопросов / ответов: | 5 / 5 | IRC-канал по теме: | #assembler | Вопрос № 178507: Доброго времени суток, уважаемые эксперты! Прошу помочь с такой задачей: необходима программа морфинга из звезды в круг. (число граней, цвет - в задаче не обозначены) . DOS, TASM.Заранее спасибо. ... Вопрос № 178653: помогите пожалуйста,эксперты!есть код программы,но проблема в том что значения записываются во внутреннюю память,а нужно чтобы записывались во внешнюю память! name var3 DSEG AT 30h CSEG AT 0h jmp mai... Вопрос № 178661: Здравствуйте уважаемые эксперты! Требуется решить такую задачку: Составить программу, выводящую на экран и в задаваемый с клавиатуры файл десятичное представление двойного факториала. Должна быть работоспособна для вычисления 1000!!. Число тож... Вопрос № 178664: Вычислить значение выражения Ax^2+Bx+C на интервале [Xmin; Xmax] с шагом 1. Вывести аргумент и значение функции в виде таблицы. Организовать вывод ФИО, уникального номера, текущего системного времени и даты. Xmin=3 Xmax=7 A=1 B=3 C=2 Процес... Вопрос № 178666: Здравствуйте уважаемые эксперты! Помогите пожалуйста решить задачу, имеется строка - предложение из нескольких слов. Написать процедуру, осуществляющую запись тех же строк словами, переписанными с конца наперед. Дополнительных массивов не исп... Вопрос № 178507: Доброго времени суток, уважаемые эксперты! Прошу помочь с такой задачей: необходима программа морфинга из звезды в круг. (число граней, цвет - в задаче не обозначены) . DOS, TASM.Заранее спасибо. Отправлен: 19.05.2010, 21:10 Вопрос задал: Виктор Никанорович, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, Виктор Никанорович. Наконец-то появилось время написать программу... Достаточно неочевидную, между прочим, т.к. необходимо знание математики.
Код: .model tiny, C .386
R equ 80 ;радиус окружности N equ 20 ;число итераций
POINT struc ;структура для хранения информации о меняющейся точке X0 dd ? ;расстояние от центра точки по Х исходной звезды FY dw ? ;индекс функции, вычисляющей Y исходной звезды Xd dd ? ;приращение по Х для следующей итерации Xi dd ? ;Х позиции точки при очередной итерации POINT ends
.code .startup call FormPoints ;формируем информацию о точках правой половины звезды
mov ax, 0013h ; vga 320x200x256 int 10h
mov ax, 0a000h mov es, ax ; es - сегмент видео
call PrintFigure,0bh ;рисуем нулевую итерацию - исходную фигуру - звезду mov ah,0 int 16h ;для начала морфинга ждем нажатия на клавишу mov cx, N ;число итераций FigureOff: call PrintFigure,0 ;вытираем старую итерацию call PrintFigure,0bh ;рисуем новую итерацию
call DELAY ;пауза
loop FigureOff ;рисуем N раз
WaitEscape: mov ah, 0 int 16h ;выходим по Esc cmp ah, 1 jne WaitEscape
;выход в DOS mov ax, 0003h ; назад в текстовый режим int 10h
mov ax, 4c00h ; bye-bye int 21h
;Формируем массив с инфой обо всех точках ;для квадрата достаточно иметь инфу о половине стороны FormPoints proc local num:word, radius:word, x2:word
lea di, pPoints ;будем хранить инфу сразу за программой mov radius, R ;радиус
;посчитаем некоторые необходимые константы ;tg(54), tg(36), sin(36), cos(18), sin(18), tg(18)
fldpi ;Пи fimul c 54 ;Пи*54 fidiv c180 ;Пи*54/180 - угол в радианах fsincos ;st = cos(54), st(1) = sin(54) fdiv ;st = st(1)/st = tg(18) fstp tg54 ;сохраним tg(54)
fldpi ;Пи fimul c36 ;Пи*36 fidiv c180 ;Пи*36/180 - угол в радианах fsincos ;st = cos(36), st(1) = sin(36) fld st(1) ;st = sin(36) fstp sin36 ;сохраним sin(36) fdivp ;st = st(1)/st = tg(36) fstp tg36 ;сохраним tg(36)
fldpi ;Пи fimul c18 ;Пи*18 fidiv c180 ;Пи*18/180 - угол в радианах fld st ;st = st(1) fsincos ;st = cos(18), st(1) = sin(18) fstp cos18 ;сохраним cos(18) fstp sin18 ;сохраним sin(18) fptan ;st(1) = tg(st) = tg(18), st = 1 fxch ;st(1) = 1 st = tg(18) fstp tg18 ;сохраним tg(18) fsub sin18 ;1-sin(18) fimul radius ;(1-sin(18))*R ;сохраним Y точки конца первого участка, понадобится дальше fst fy1 ;y1 = (1-sin(18))*R fmul tg18 ;y1 * tg(18) - Х координата первого поворота ;сох раним Х точки конца первого участка, понадобится дальше fst fx1 ;x1 = (1-sin(18))*R*tg(18) fistp num ;num - число точек по Х до первого поворота
;первый участок - правый отрезок верхнего луча mov cx, num ;число точек первого участка mov num, 0 ;начинаем с х=0 X1Loop: fild num ;x fst [POINT ptr di].X0 ;сохраним, как (float)x0 fstp [POINT ptr di].Xi ;и как начальный x mov [POINT ptr di].FY, offset CalcY1 ;функция вычисления Y ;расчитаем приращение по Х для морфинга по лучам из (0,0) call CalcDelta, N, radius add di, size POINT ;на следующую точку inc num ;x=x+1 loop X1Loop ;по всем точкам первого участка
;второй участок - горизонталь правого луча ;посчитаем крайний правый Х fld cos18 ;cos(18) fimul radius ;R*cos(18) fistp x2 ;х2=R*cos(18)
X2Loop: fild num ;x fst [POINT ptr di].X0 ;сохраним, как (float)x0 fstp [POINT ptr di].Xi ;и как начальный x mov [POINT ptr d i].FY, offset CalcY2 ;расчитаем приращение по Х для морфинга по лучам из (0,0) call CalcDelta, N, radius add di, size POINT ;на следующую точку inc num ;x=x+1 mov ax, num ;дошли ли до конца луча? cmp ax, x2 jbe X2Loop ;по всем точкам второго участка
;третий участок - нижний отрезок правого луча ;посчитаем Х конца отрезка fld sin18 ;sin(18) fimul c2 ;2*sin(18) fld1 ;1 faddp ;1+2*sin(18) fmul fx1 ;х1*(1+2*sin(18)) fistp x2 ;x2=х1*(1+2*sin(18))
dec num ;вернемся на последнюю точку X3Loop: dec num ;возвращаемся назад по другому отрезку mov ax, num cmp ax, x2 ;дошли до конца отрезка? jb X4Start fild num ;x fst [POINT ptr di].X0 ;сохраним, как (float)x0 fstp [POINT ptr di].Xi ;и как начальный x mov [POINT ptr di].FY, offset CalcY3 call CalcDelta, N, radius add di, size POINT ;на следующую точку jmp X3Loop ;по всем точкам третьего участка
;четвертый участок - правый отрезок нижнего луча ;посчитаем Х конца отрезка X4Start: fld sin18 ;sin(18) fld1 ;1 faddp ;1+s in(18) fimul c2 ;2*(1+sin(18)) fmul fx1 ;x1*(2*(1+sin(18))) fistp x2 ;x2=x1*(2*(1+sin(18)))
inc num ;вернемся на последнюю точку X4Loop: inc num ;идем по другому отрезку mov ax, num cmp ax, x2 ;дошли до конца отрезка? ja X5Start fild num ;x fst [POINT ptr di].X0 ;сохраним, как (float)x0 fstp [POINT ptr di].Xi ;и как начальный x mov [POINT ptr di].FY, offset CalcY1 ;функция такая же, т.к. та же прямая call CalcDelta, N, radius add di, size POINT ;на следующую точку jmp X4Loop ;по всем точкам четвертого участка
;пятый участок - левый отрезок нижнего луча X5Start: dec num ;вернемся на последнюю точку X5Loop: dec num ;идем по последнему отрезку cmp num, 0 jl FPRet ;до 0 fild num ;x fst [POINT ptr di].X0 ;сохраним, как (float)x0 fstp [POINT ptr di].Xi ;и как начальный x mov [POINT ptr di].FY, offset CalcY4 call CalcDelta, N, radius add di, size POINT ;на следующую точку jmp X5Loop ;по всем точкам второго участка FPRet: mov LAddr, di ;сохраним адрес для проверки конца ; sub di, size POINT ; fld [POINT ptr di].X0 ; mov ax, [POINT ptr di].FY ; call ax ; add ax, radius ; mov num, ax ; fild num ; mov num, N ; fidiv num ; fstp [POINT ptr di].Xd ret FormPoints endp
;Расчет приращения по Х для морфинга ;Параметры: число итераций морфинга и радиус окружности ;di - адрес структуры POINT ;DeltaX = (R/(sqrt(x0^2+y0^2)-1)*x0 CalcDelta proc, Count:word, CircusRadius:word local yyy:word ;переменная для обмена данными с сопроцессором fld [POINT ptr di].X0 ;Х0 точки на звезде fld st ;сохраним в стеке для дальнейших вычислений fld st fld st fmulp ;st=x0*x0 fxch ;st=x0, st(1)=x0*x0 mov ax, [POINT ptr di].FY ;функция вычисления y call ax ;ax=y0=y(x0) mov yyy, ax ;сохраним fild yyy ;y0 fld st ;st(1)=st=y0 fmulp ;y0*y0 faddp ;x0*x0+y0*y0 fsqrt ;sqrt(x0*x0+y0*y0) fild CircusRadius ;радиус fdivrp ;R/sqrt(x0*x0+y0*y0) fld1 ;1 fsubp ;R/sqrt(x0*x0+y0*y0) - 1 fmulp ;x0*(R/sqrt(x0*x0+y0*y0) - 1) - длина добавки по Х fidiv Count ;разделим на число итераций fstp [POINT ptr di].Xd ;сохраним приращение по Х ret CalcDelta endp
;Вычисление Y для очередной итерации морфинга ;Точки строятся на продолжениях лучей из (0,0) до (x0,y0), ; где (x0,y0) - точки на звезде ;y = x * y0 / x0 CalcY proc local yyy:word ;проверим, равен ли нулю x0, иначе будет деление на 0 cmp [POINT ptr di].X0, 0 je ForXeq0 fld [POINT ptr di].X0 ;x0 fld st ;st=st(1)=x0 call ax ;ax=y0=y(x0) mov yyy, ax fild yyy ;st=y0 fdivrp ;st=y0/x0 fmulp ;st=x*y0/x0 fistp yyy mov ax, yyy ;ax=y=[x*y0/x0] jmp CYRet ForXeq0: call ax ;для x0=0 ax=y0=y(x0) CYRet: ret CalcY endp
;Функци и расчета y0 для участков звезды ;st = x0 ;результат - целое в ax CalcY1 proc ;первый участок local yyy:word mov yyy, R< br> fdiv tg18 fild yyy fsubrp fistp yyy mov ax, yyy ;ax=y0=R-x0/tg(18) ret CalcY1 endp
CalcY2 proc ;второй участок local yyy:word fistp yyy mov yyy, R fild yyy fsub fy1 fistp yyy mov ax, yyy ;ax=y0=R-y1 ret CalcY2 endp
CalcY3 proc ;третий участок local yyy:word fmul tg36 fld fx1 fdiv sin36 fsubp fistp yyy mov ax, yyy ;ax=y0=x0*tg(36)-x1/sin(36) ret CalcY3 endp
CalcY4 proc ;четвертый участок local yyy:word fdiv tg54 fchs fld fx1 fdiv sin36 fsubp fistp yyy mov ax, yyy ;ax=y0=-x0/tg(54)-x1/sin(36) ret CalcY4 endp
;Вывод одной итерации цветом colour PrintFigure PROC colour:word uses cx local X1Num:word,Y1num:word,X2Num:word,Y2num:word,RR:word mov RR, R ;радиус для вычислений lea di, pPoints ;адрес массива точек mov bx, size POINT ;длина одного элемента neg bx ;будем адресовать предыдущий э лемент
;получаем координаты первой точки fld [POINT ptr di].Xi ;Хi fist X1Num ;X1=Xi mov ax, [POINT ptr di].FY call CalcY ;ax = FY(X1) mov Y1Num, ax ;Y1 = ax PrintLoop: add di, size POINT ;на следующую точку mov ax, LAddr ;отрабатываем до предпоследней точки! sub ax, size POINT cmp di, ax jae PFRet ;получаем координаты второй точки fld [POINT ptr di].Xi ;Xi fist X2Num ;X2=Xi mov ax, [POINT ptr di].FY call CalcY ;ax = FY(X2) mov Y2Num, ax ;Y2 = ax
;выводим отрезок в правой половине push colour ;цвет mov ax, 100 sub ax, Y2Num ;Y2 выше центра push ax mov ax, 160 add ax, X2Num ;X2 справа центра push ax mov ax, 100 sub ax, Y1Num ;Y1 выше центра push ax mov ax, 160 add ax, X1Num ;X1 справа центра push ax call line add sp, 5*2
;выводим отрезок в левой половине push colour ;цвет mov ax, 100 sub ax, Y2Num ; Y2 выше центра push ax mov ax, 160 sub ax, X2Num ;X2 слева центра push ax mov ax, 100 sub ax, Y1Num ;Y1 выше центра push ax mov ax, 160 sub ax, X1Num ;X1 слева центра push ax call line add sp, 5*2
;копируем правую точку (x2,y2) на место первой (x1,y1) для следующего отрезка mov ax, X2Num mov X1Num, ax mov ax, Y2Num mov Y1Num, ax
cmp colour, 0 ;после вытирания цветом 0 сдвигаем Xi на DeltaX jne PrintLoop fld [POINT ptr di+bx].Xi ;перейдем к следующей точке fadd [POINT ptr di+bx].Xd fstp [POINT ptr di+bx].Xi ;Xi=Xi+Xd jmp PrintLoop PFRet: cmp colour, 0 ;после вытирания цветом 0 сдвигаем Xi на DeltaX jne PFrr fld [POINT ptr di+bx].Xi ;перейдем к следующей точке fadd [POINT ptr di+bx].Xd fstp [POINT ptr di+bx].Xi ;Xi=Xi+Xd PFrr: ;соединим концы горизонтальной линией push colour ;цвет mov ax, 100 sub ax, Y1Num ;Y2 выше центра pu sh ax mov ax, 160 sub ax, X1Num ;X2 слева центра dec ax push ax mov ax, 100 sub ax, Y1Num ;Y1 выше центра push ax mov ax, 160 add ax, X1Num ;X1 справа центра push ax call line add sp, 5*2
ret PrintFigure ENDP
;рисуем линию (x1,y1)-(x2,y2) цветом color Line proc uses di bx, x1:word, y1:word, x2:word, y2:word, color:byte local i:word, \ ;для работы со сопроцессором delta_x:word, \ ;длина проекции на ось абсцисс delta_y:word, \ ;длина проекции на ось ординат incx:word, \ ;приращение по X incy:word ;приращение по Y
;определим длину проекции на ось абсцисс и шаг по оси X mov ax, x2 sub ax, x1 ;ax=x2-x1;
;определим шаг по X (+1 если вперед, -1 если назад, 0 если не меняется) mov incx, 0 ;пусть incx=0 test ax, ax ;ax=delta_x jz set_delta_x ;не меняется jg set_x_1 ;вперед? dec incx ;назад, значит incx=-1 neg ax ;найдем ax=abs(delta_x) jmp set_delta_x ;на сохранение set_x_1: inc incx ;вперед, значит incx=1; set_delta_x: mov delta_x, ax ;delta_x = abs(x2-x1)
;определим длину проекции на ось ординат и шаг по оси Y mov ax, y2 sub ax, y1 ;ax=y2-y1;
;определим шаг по Y (+1 если вперед, -1 если назад, 0 если не меняется) mov incy, 0 ;пусть incy=0 test ax, ax ;ax=delta_y jz set_delta_y ;не меняется jg set_y_1 ;вперед? dec incy ;назад, значит incy=-1 neg ax ;найдем ax==abs(delta_y) jmp set_delta_y ;на сохранение set_y_1: inc incy ;вперед, значит incy=1; set_delta_y: mov delta_y, ax ;delta_y=abs(y2-y1) ;определим большее из проекций как основное напрвление cmp ax, delta_x ;ax=delta_y jge from_y ;y будет основным cmp delta_x, 0 ;проверим, чтобы не было delta_x=0 (для точки), jz Line_ret ; иначе будет деление на 0 ;delta_x>delta_y && delta_x!=0 ;основное направление - по оси X fild delta_y fidiv delta_x ;st=k=(float)(delta_y/delta_x)
;for (int i=0;i<delta_x;i++) xor cx, cx ;cx=i jmp cmp_i_x ;на проверку i&l t;delta_x x_loop: ;тело цикла mov i, cx ;запишем переменную цикла в память (для сопроцессора) fld st ;st=st(1)=k fimul i ;st=k*i fimul incy ;st=incy*k*i call floor ;округлим до целого в большую сторону fistp i ;сохраним в переменной mov ax, i ;относительный номер строки на экране add ax, y1 ;добавим до ординаты начальной точки mov dx, 320 ;получим индекс начала строки экрана в сегменте экрана imul dx ; для этого умножим на длину в байтах одной стоки mov bx, ax ;сохраним bx=y=(y1+floor(incy*k*i))*320 ;посчитаем X mov ax, incx ;X меняется ровно на шаг приращения, imul cx ; умноженному на индекс точки add ax, x1 ;добавим абциссу начальной точки ax=x=x1+incx*i
add ax, bx ;сложим с индексом начала строки mov di, ax ;будем адресовать через di
mov al, color ;цвет точки mov es:[di], al ;рисуем!
inc cx ;на следующую точку cmp_i_x: cmp cx, delta_x ;дошли до конц а? jl x_loop jmp Line_ret ;на выход from_y: ;вдоль оси Y fild delta_x fidiv delta_y ;st=k=(float)(delta_x/delta_y)
;for (int i=0;i<delta_y;i++) xor cx, cx ;cx=i jmp cmp_i_y ;на проверку i<delta_y y_loop: ;тело цикла mov ax, incy ;Y меняется ровно на шаг приращения, imul cx ; умноженному на индекс точки add ax, y1 ;добавим абциссу начальной точки ax=y=y1+incy*i mov dx, 320 ;получим индекс начала строки экрана в сегменте экрана imul dx ; для этого умножим на длину в байтах одной стоки mov bx, ax ;сохраним bx=y=(y1+incy*i)*320 ;посчитаем X mov i, cx ;запишем переменную цикла в память (для сопроцессора) fld st ;st=st(1)=k fimul i ;st=k*i fimul incx ;st=incx*k*i call floor ;округлим до целого в большую сторону fistp i ;сохраним в переменной mov ax, i ;относительный номер строки на экране add ax, x1 ;ax=x=x1+floor(incx*k*i)
add ax, bx ;сл ожим с индексом начала строки mov di, ax ;будем адресовать через di
mov al, color ;цвет точки mov es:[di], al ;рисуем!
inc cx ;на следующую точку cmp_i_y: cmp cx, delta_y ;дошли до конца? jl y_loop Line_ret: fistp i ;удалим из сопроцессора k ret Line endp
;округление до целого в большую сторону ;округление по умолчанию, до ближайщего, не устраивает floor proc local CtrlWordOld:word, CtrlWordNew:word fstcw CtrlWordOld ;сохраним управляющее слово fclex ;сбросим исключения mov CtrlWordNew,0763h ;установим необходимое значение управляющего слова fldcw CtrlWordNew ;загружаем управляющее слово frndint ;округляем st до целого fclex ;сбросим исключения fldcw CtrlWordOld ;восстановим старое управляющее слово ret floor endp
;пауза ~40мс. Под Windows весьма условно, скорее всего будет больше time equ 4 ;число интервалов по 10мс DELAY: pusha ;сохраним все рег истры mov ah,2dh ;сбросим "локальное" системное время (под nt+ все равно не поменяет) xor cx,cx xor dx,dx int 21 h dl2: mov ah,2ch int 21h ;читаем время ;считаем сотни мс mov al,100 mul dh ;секунды умножаем на 100 -> ax = количество интервалов по 10мс xor dh,dh ;dx - число сотых xchg ax,dx ;поменяем местами mov cl,10 div cl ;ax = количество интервалов по 10мс из сотых add ax,dx ;складываем с количеством из секунд cmp ax,time ;сравним с ожидаемым интервалом jl dl2 ;ждем, если меньше popa ;восстановим все регистры ret
.data ;константы для вычислений c2 dw 2 ;при умножении на 2 c18 dw 18 ;18 градусов c36 dw 36 ;36 градусов c54 dw 54 ;54 градусов c180 dw 180 ;180 градусов для перевода в радианы
.data? LAddr dw ? ;адрес конца массива точек sin18 dd ? ;float для хранения sin(18) cos18 dd ? ;float для хранения cos(18) tg18 dd ? ;float для хранения tg(18) fx1 dd ? ;Х конца первого отрезка fy1 dd ? ;Y конца первого отрезка sin36 dd ? ;float для хранения sin(36) tg36 dd ? ;floa t для хранения tg(36) tg54 dd ? ;float для хранения tg(54) pPoints label DWORD ;с этого адреса будем хранить данные о точках
end
----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 31.05.2010, 01:58 Номер ответа: 261769 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261769 на номер 1151 (Россия) | Еще номера » | Вопрос № 178653: помогите пожалуйста,эксперты!есть код программы,но проблема в том что значения записываются во внутреннюю память,а нужно чтобы записывались во внешнюю память!
name var3 DSEG AT 30h CSEG AT 0h jmp main Array: dw 0FEh, 0FDh, 0FCh, 0EDh, 0FAh, 0FFh, 0F9h, 0EFh, 0EEh, 0FBh main: mov dptr, #Array mov r0, #10 clr a mov r1, a mov r2, a mov r3, a clr c mov a, #1 movc a, @a + dptr mov r1, a round: djnz r0, Toonel jmp exit Toonel: clr c clr a mov r2, a mov r3, a inc dptr inc dptr mov a, #1 movc a, @a + dptr mov r2, a subb a, r1 mov r3, a JC round clr a mov a, r2 mov r1, a jmp round exit: NOP END Отправлен: 26.05.2010, 01:31 Вопрос задал: bass, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, bass. Предлагаю Вам свое решение:
Код: ExtMem equ 0 ;адрес внешней памяти для найденного максимального значения max equ 8 ;временное максимальное значение Stack equ 60h ;стек
org 9000h ;адрес начала программы main: mov sp,#Stack ;задаем вершину стека
mov dptr,#Array ;адрес массива байт mov r2,#Len ;длина массива mov max,#0 ;максимум mov r4,#0 ;индекс в массиве loop: ;цикл поиска максимума mov a,r4 ;индекс movc a,@a + dptr ;читаем очередной байт cjne a,max,cmp_max ;сравниваем, если не равно, то на метку jmp next ;если равно, то на следующий байт cmp_max: jc next ;если очередной байт < max, то на следующий mov max, a ;иначе сохраняем, как максима льный next: ;на следуэщий байт inc r4 ;готовим индекс для следующего djnz r2,loop ;r2=r2-1, циклим, пока r2!=0
mov dptr,#ExtMem ;адрес во внешней памяти, куда запишем результат mov a,max ;максимальное значение movx @dptr,a ;сохраняем
jmp $ ;бесконечный цикл на месте
Array dw 0FEh,0FDh,0FCh,0EDh,0FAh,0FFh,0F9h,0EFh,0EEh,0FBh Len equ $-Array ;длина массива
END ----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 26.05.2010, 02:42 Номер ответа: 261649 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Оценка ответа: 5 Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261649 на номер 1151 (Россия) | Еще номера » | Вопрос № 178661: Здравствуйте уважаемые эксперты! Требуется решить такую задачку:
Составить программу, выводящую на экран и в задаваемый с клавиатуры файл десятичное представление двойного факториала. Должна быть работоспособна для вычисления 1000!!. Число тоже нужно задавать с клавиатуры с контролем ввода.
Двойной факториал, это например:
Если число четное, то двойной факториал будет: 2*4*6*8... Если нечетное, то: 1*3*5*7...
Есть идея как сделать, чтоб было без проверки на четность и нечетность. Нужно взять введенное число и вычислять факториал с конца, например, если 10, то 10*8*6*4*2, т.е. loop до 2. Прошу написать программу с подробными комментарями, та как мне придется объяснять как она работает! (Желательно с описанием алгоритма!) Заранее спасибо! Отправлен: 26.05.2010, 06:02 Вопрос задал: Петров Юрий Иванович, Посетитель Всего ответов: 1 Страница вопроса » Отвечает amnick, Студент : Здравствуйте, Петров Юрий Иванович.
Небольшой поиск по сайту дает ссылку на очень похожий вопрос 155765. В приведенном там решении Зенченко Константина Николаевича длинное число хранится в массиве поразрядно с основанием системы счисления 10.
Представление длинных чисел как массива отдельных цифр является стандартным подходом, различается только основание системы счисления. Для повышения эффективности вычислений и экономии памяти основание системы счисления следует выбирать возможно большим. Однако, если оно не кратно 10, то усложняется ввод и вывод чисел в обычном строковом представлении.
В приложении приведено решение с основанием системы счисления 10000 (для 16-битного CPU), т.е. в каждом разряде хранится не одна, а 4 десятичных цифры. Если использовать 32-битные регистры, то основание системы счисления можно увеличить.
Подробно можно почитать в статье "Длинная арифметика" (В.Гольдштейн).
Использовался TASM. Компилировать в COM-файл.
Успехов! Приложение: Ответ отправил: amnick, Студент Ответ отправлен: 26.05.2010, 18:10 Номер ответа: 261685 Оценка ответа: 5 Комментарий к оценке: Спасибо огромное! Программа работает и написана отлично, все с комментариями) Похожий вопрос 155765 я видел и пробовал в нем разбираться, но алгоритма до конца не понял, пытался поменять шаг на 2, но не нашел где! И спасибо за подробное описание, буду разбираться) Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261685 на номер 1151 (Россия) | Еще номера » | Вопрос № 178664: Вычислить значение выражения Ax^2+Bx+C на интервале [Xmin; Xmax] с шагом 1. Вывести аргумент и значение функции в виде таблицы. Организовать вывод ФИО, уникального номера, текущего системного времени и даты. Xmin=3 Xmax=7 A=1 B=3 C=2
Процессор - 8086 Ассемблер - TASM v. 2.51 Платформа - MS-DOS Модель памяти - не имеет значения
Сам написал код (немного помог Лысков Игорь Витальевич). Закавыка в том, что неправильно выводится дата, а именно год. Оформлял кусок вывода даты в виде отдельной программы - все работает правильно. Помогите найти ошибку. Отправлен: 26.05.2010, 16:49 Вопрос задал: Никифоров Павел, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Airyashov, Студент : Здравствуйте, Никифоров Павел. push cx неверно написано наверное 'С' русская, здесь
Код: PUSH СX ; сохраняем год в стеке PUSH DX ; сохраняем месяц и день в стеке также используется 'C' - это зарезервированное слово Ответ отправил: Airyashov, Студент Ответ отправлен: 26.05.2010, 17:10 Номер ответа: 261682 Оценка ответа: 1 Комментарий к оценке: Если бы было русское C, это отловил бы транслятор. Учите матчасть. Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261682 на номер 1151 (Россия) | Еще номера » | Вопрос № 178666: Здравствуйте уважаемые эксперты!
Помогите пожалуйста решить задачу, имеется строка - предложение из нескольких слов. Написать процедуру, осуществляющую запись тех же строк словами, переписанными с конца наперед. Дополнительных массивов не использовать. Исходная строка вводится с клавиатуры. Задача под TASM 16 бит.
Например, исходная строка: привет мир
В результате должно получиться: тевирп рим
С ассемблером в плохих отношениях, поэтому нужны подробные комментарии и объяснения. Отправлен: 26.05.2010, 18:52 Вопрос задал: Петров Юрий Иванович, Посетитель Всего ответов: 1 Страница вопроса » Отвечает amnick, Студент : Здравствуйте, Петров Юрий Иванович.
Программа с комментариями — в приложении. Требуемая по условию процедура — invert_words_in_string. Компилировать в COM-файл. Если есть вопросы, то обращайтесь в мини-форум.
Успехов! Приложение: Ответ отправил: amnick, Студент Ответ отправлен: 26.05.2010, 20:50 Номер ответа: 261687 Оценка ответа: 5 Комментарий к оценке: Спасибо! Вы мне очень помогли) Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261687 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |