Операции над натуральными числами
Модератор: Andy
Здравствуйте.Дано натуральное число n. Вычислить: (1-1/2^n)(1-1/3^n)(1-1/4^n)…(1-1/n^n).компилятор tasm.
Для начала решил заменить возведение в степень на произведение n, (1-1/2n)(1-1/3n)(1-1/4n).(1-1/nn) и написать в vs с++
Проверьте, пожалуйста, сам алгоритм, а так же возникает ошибка при делении (деление на ноль)
Код: Выделить всё
short n = 5;
__asm
{
mov cx,n
mov dx,1
lp1:
mov ax,cx
imul n
mov bx,ax
mov ax,1
cwd
idiv bx
mov bx,1
sub bx,ax
imul dx
mov dx,ax
loop lp1
mov n,dx
}
cout<<n;
getch();
имхо, здесь проще использовать FPU. Более того он здесь просто необходим 
Для возведения в степень, при небольших N, действительно лучше использовать циклическое умножение. Однако в этом случае ньюанс, при использовании 16 битных команд умножения мы сможем посчитать не более, чем 6^6. Посему настоятельо рекомендую использовать 32 битное умножение. Это расширит возведение до 9^9. Возведение в степень удобно оформить в виде процедуры, которой в регистре EAX передается возводимое число, а в регистре EBX - показатель степени. После исполнения она должна вернуть в EAX результат.
Далее, схематично обрисуем:
а) R = 1, Х = 1
б) Х = Х + 1
в) Вызывается процедура возведения в степень, А = X^N
г) Вычисляется R = R * (1 - 1/А)
д) Если Х не равно N, то идем к (б)

Для возведения в степень, при небольших N, действительно лучше использовать циклическое умножение. Однако в этом случае ньюанс, при использовании 16 битных команд умножения мы сможем посчитать не более, чем 6^6. Посему настоятельо рекомендую использовать 32 битное умножение. Это расширит возведение до 9^9. Возведение в степень удобно оформить в виде процедуры, которой в регистре EAX передается возводимое число, а в регистре EBX - показатель степени. После исполнения она должна вернуть в EAX результат.
Далее, схематично обрисуем:
а) R = 1, Х = 1
б) Х = Х + 1
в) Вызывается процедура возведения в степень, А = X^N
г) Вычисляется R = R * (1 - 1/А)
д) Если Х не равно N, то идем к (б)
It's a long way to the top if you wanna rock'n'roll
Пример процедуры возведения в степень целого числа EAX в степень EBX (без проверки правильности параметров, например если EBX = 0 или очень большое число)
Пример вычисления R = R*(1 - 1/X^N)
Теперь осталось все это увязать =)
Код: Выделить всё
SeriesMultiply proc near
push ecx
mov ecx, eax
@loop1:
cmp ebx, 2
jc @exit
imul ecx
dec ebx
jmp @loop1
@exit:
pop ecx
retn
SeriesMultiply endp
Код: Выделить всё
mov eax, X
mov ebx, N
call SeriesMultiply
mov temp, eax
fld1
fidiv temp
fld1
fsub st(1)
fmul R
fstp R
It's a long way to the top if you wanna rock'n'roll
К сожалению не получается это все увязать , не хватает знанийТеперь осталось все это увязать =)

Код: Выделить всё
.486
MODEL use16 small ;модель памяти
STACK 256 ;размер стека
include mac.inc ;подключение файла с макросами
.data
temp dd ?
N dd ?
R dd 1
X dd 1
vvod db 10,13,10,13,'Введите натуральное число n - $'
.code
assume ds:@data,es:@data
main: ;начало программы
mov ax,@data
mov ds,ax
xor ax,ax
push ds
pop es
finit
ClearScreen
mov dx,offset vvod
mov ah,09h
int 21h
mov ah,01h
int 21h
mov [eax],al
mov N,eax
;mov dl,[eax]
; mov ah,02h
; int 21h
mov eax, X
mov ebx, N
call SeriesMultiply
mov temp, eax
fld1
fidiv temp
fld1
fsub st(1),st(0)
fmul R
fstp R
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SeriesMultiply proc near
push ecx
mov ecx, eax
@loop1:
cmp ebx, 2
jc @exit
imul ecx
dec ebx
jmp @loop1
@exit:
pop ecx
retn
SeriesMultiply endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov dl,[ecx]
mov ah,02h
int 21h
MOV ax,4c00h
INT 21h
end main