Algorithm 实现根计算功能

Algorithm 实现根计算功能,algorithm,function,math,equation,Algorithm,Function,Math,Equation,实现各种数学函数非常简单整数mul(整数,整数),intpow(int,int),偶数双除法(浮点,浮点)易于实现,可以通过循环或递归实现。(这些方法与用手或在头脑中执行这些功能的方法相同。)要进行乘法,只需重复相加。要除法,请反复减去它。为了获得能量,反复乘法。等等 然而,我一直想知道的一个数学函数是根。例如,您将如何编写一个函数来计算一个数字的平方根(或立方体等)(即,double root(float num,float root);)?我试着四处看看,却找不到一个算法或方法来实现这一点

实现各种数学函数非常简单<代码>整数mul(整数,整数)
intpow(int,int),偶数<代码>双除法(浮点,浮点)易于实现,可以通过循环或递归实现。(这些方法与用手或在头脑中执行这些功能的方法相同。)要进行乘法,只需重复相加。要除法,请反复减去它。为了获得能量,反复乘法。等等

然而,我一直想知道的一个数学函数是根。例如,您将如何编写一个函数来计算一个数字的平方根(或立方体等)(即,
double root(float num,float root);
)?我试着四处看看,却找不到一个算法或方法来实现这一点

当我试图手工计算一个根时,我通常使用猜测法(从一个近似数字开始,加一个分数,乘以,看看它有多远,再加一个小分数,乘以,再次检查,然后重复,直到满意为止)。我想这可能行得通,但肯定有更好更快的方法(不管计算机的速度比手工快多少)

显然,LUT是不相关的,因为它必须具有足够的通用性才能接受任何操作数(除非您编写的是一个具有有限数据集的游戏)。文章提到了猜测方法,列出了一些古老的方法(在计算机发明之前很久),以及一些纯数学甚至微积分方法(包括一些以“无穷大”为组成部分的方法)。只有那些似乎与电子产品有关的人使用技巧或逻辑。(这只是平方根,更不用说立方根之类的了。)

没有简单的根计算方法吗?计算器是怎么做到的?计算机是如何做到的?(不,简单地执行
双功率(a,0.5);
不起作用,因为那样的话
双功率(float,float)
将如何实现?)


我是否只是错误地将根函数与更简单的函数分组?它们是否比看上去更复杂?

有一个简单的实现方法,直接从您所陈述的文章链接而来。它来自于。

有几种可能性。有两种不同的迭代方法,例如二分法或牛顿法。至于使用pow
,有些计算机(例如x86)有一条指令要执行(至少是部分)将数字提升为幂的操作,因此这纯粹是编写一个框架的问题

这是牛顿平方根法的汇编语言实现,在本例中仅处理16位整数,但相同的基本思想适用于其他类型。我大约在20年前写过这篇文章,所以它是针对没有浮点硬件的16位CPU

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等)上,这样的代码非常常见。

这取决于您希望的通用性。例如,如果要计算(-4.2)0.23,则需要复杂的算术运算。正如Mat指出的,对于整数n和正x,有计算x1/n的快速算法。如果您希望xy代表正x和任意y,那么日志和指数将起作用。

是的,不要通过重复的加法进行乘法或除法。这是相当多的灰尘,但是。