Есть несколько возможностей. Есть несколько разных итеративных подходов, таких как бисекция или ньютоновский подход. Что касается использования pow
, то на некоторых компьютерах (например, x86) есть инструкция, чтобы сделать (по крайней мере, часть) возведение числа в степень, так что это просто вопрос написания некоторой структуры вокруг этого.
Вот реализация на языке ассемблера метода Ньютона для квадратного корня, в данном случае работающая только с 16-разрядными целыми числами, но та же основная идея применима и к другим типам. Я написал это около 20 лет назад, так что это было для 16-битных процессоров без аппаратного обеспечения с плавающей запятой.
isqrt proc uses di, number:word
;
; uses bx, cx, dx
;
mov di,number
mov ax,255
start_loop:
mov bx,ax
xor dx,dx
mov ax,di
div bx
add ax,bx
shr ax,1
mov cx,ax
sub cx,bx
cmp cx,2
ja start_loop
ret
isqrt endp
Вот некоторый код для x87 для вычисления произвольных степеней:
pow proc
; x^y = 2^(log2(x) * y)
fyl2x
fld st(0)
frndint
fld1
fscale
fxch st(2)
fsubrp
f2xm1
fld1
faddp
fmulp
ret
endp
Обратите внимание, однако, что вы обычно не хотите реализовывать умножение путем простого многократного сложения или деления путем повторного вычитания. Скорее, вы хотите сдвинуть и сложить / вычесть последовательные степени двух, чтобы получить результат намного быстрее.
Вот некоторый код, который показывает общую идею:
mult proc
; multiplies eax by ebx and places result in edx:ecx
xor ecx, ecx
xor edx, edx
mul1:
test ebx, 1
jz mul2
add ecx, eax
adc edx, 0
mul2:
shr ebx, 1
shl eax, 1
test ebx, ebx
jnz mul1
done:
ret
mult endp
Это довольно бессмысленно для x86, потому что в него встроены инструкции умножения, но на старых процессорах (PDP-11, 8080, 6502 и т. Д.) Такой код был вполне распространенным.