Операции над натуральными числами

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

Модератор: Andy

Ответить
Akimich
Сообщения: 6
Зарегистрирован: 06 июл 2010, 07:09

Здравствуйте.Дано натуральное число n. Вычислить: (1-1/2^n)(1-1/3^n)(1-1/4^n)…(1-1/n^n).компилятор tasm.
Akimich
Сообщения: 6
Зарегистрирован: 06 июл 2010, 07:09

Для начала решил заменить возведение в степень на произведение 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();
Проверьте, пожалуйста, сам алгоритм, а так же возникает ошибка при делении (деление на ноль)
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

имхо, здесь проще использовать FPU. Более того он здесь просто необходим :)
Для возведения в степень, при небольших 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
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Пример процедуры возведения в степень целого числа EAX в степень EBX (без проверки правильности параметров, например если EBX = 0 или очень большое число)

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

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
Пример вычисления R = R*(1 - 1/X^N)

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

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
Akimich
Сообщения: 6
Зарегистрирован: 06 июл 2010, 07:09

Теперь осталось все это увязать =)
К сожалению не получается это все увязать , не хватает знаний :(

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

.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	
Ответить