计算正实数的乘法逆

时间:2013-03-13 08:48:05

标签: c algorithm math

我想在不使用除法的情况下计算正实数的乘法逆。在阅读了Newton Raphson方法的各个页面之后,我实现了以下用于计算逆的代码:

#define PRECISION 0.1e-5
double inverse(double num) {
    double ans = num;
    while (ans * num > 1 + PRECISION || ans * num < 1 - PRECISION) {
        ans = ans * (2 - num * ans);
    }
    return ans;
}

现在,问题是,我实际上没有得到逆值。循环无限循环。

所以,我注意到第一的事情是: ans的值变为否定,我添加了一个声明if (ans < 0) ans *= -1;
,以便ans始终保持正面。

第二点被注意到: 如果我的ans = 0.5初始化,那么我会得到num = (1, 2, 3, 5)的几个值的正确答案。

所以,我的假设是,由于变量ans的初始化不恰当,实现无效。

所以,最后我的问题:
1 。这个方法实际上可以用来计算所有正实数的倒数吗?
2 。如果是,那么在使用Newton Raphson方法时,假设初始值是否需要任何条件?
3 。有没有其他更好的方法来计算倒数而不使用除法?

修改

感谢您的回答。所以,正如答案中所提到的,我将ans的初始值更改为PRECISION并且它有效!此外,由于num上的特定最大限额的初始值很有用,ans永远不会变为负值,因此不需要我最初添加的否定检查条件。

所以,这是工作代码(至少适用于我给出的输入。)

double inverse(double num) {
    // Added to make it valid for all inputs.
    // For a too large number under the precision constraint, the answer is 0.
    if (num > 999999)
        return 0;
    double ans = PRECISION;
    while (ans * num > 1 + PRECISION || ans * num < 1 - PRECISION) {
        ans = ans * (2 - num * ans);
    }
    return ans;
}

2 个答案:

答案 0 :(得分:4)

您应该从(0,2 / num)中选择初始近似值。如果从2 / num的另一侧选择它,则该方法可能不会收敛:近似将超过0并且序列将倾向于-∞。

要到达间隔,让我们看看ans*(2-num*ans)改变符号的位置:当2-num * ans&lt;时,它变为负值。 0,或当ans> 2 / NUM。所以最初ans应该小于2 / num。

为了能够选择一个好的初始近似值,你必须先了解浮点数的表达方式。通常,计算机使用x = s * m * 2 e ,其中s是符号,m(“尾数”)在(0.5,1)中,e(“指数”)是整数。现在1 / x = s * 1 / m * 2 -e ,因此问题减少到计算范围(0.5,1)中的数字的倒数,并且在该范围内,您可以使用例1作为初始猜测。显然,该范围内的最佳初始猜测是48/17 - 32/17*m

对于所有数字s * m * 2 e 应该起作用的一个初始猜测是s * 2 -e 。在C中,这可以计算为:

double ans = num;
// Initial guess: ans = 2**(-floor(log num))
long int *t = (long int*)(&ans);
*t = (*t & (0x1l<<63)) | (~*t & (0x3FFl << 52)) - (0x1l << 52);
      /* sign */              /* negative exponent */

(注意:我没有检查边缘条件。)

答案 1 :(得分:0)

为了近似x的倒数,仅使用乘法和减法,可以猜测数字y,然后用2y-xy ^ 2重复地替换y。一旦y的变化变得(并且保持)足够小,y就是x的倒数的近似值。

ans =(2 * ans) - (num * ans * ans);

请添加parantheses并尝试

在建设性数学中,对于实数x具有倒数,x≠0是不够的。必须给出有理数r,使得0 <0。 r&lt; | X |。就前一段中的近似算法而言,需要证明y的变化最终会变得任意小。的 =&GT;所有实数的乘法逆数不能通过此方法推导

每个非零元素具有乘法逆的环是除环;同样,它所代表的代数是一个除法代数。

你想使用模数吗?在模运算中,a的模乘法逆也被定义:它是数x,使得ax≡1(mod n)。当且仅当a和n是互质时,这种乘法逆存在。

_EDIT_ _ ____

最初注意到     ans = num;     ans = 2 * ans-num * ans * ans; =&GT; ans = 2 * ans - 3 * ans = -1 * ans

所以它总是一个负值。相信初始化为num不是一个好主意。尝试将ans设置为1