为什么我在自己的第 n 根代码中得到这个结果?
Why I get this result in my own code for the nth root?
我正在尝试编写自己的代码来计算数字的 n 次方根。它适用于数量级为 109 的数字,但对于更大的数字,它给了我奇怪的东西。
double nroot(double a, double b) {
int j;
double i, wtemp, w, xf, x, bgint, lsint, eps = 0.000000001, delta;
if (b == 0)
return 0;
if (a == 1)
return b;
while (xf < (int)b) {
i++;
xf = power(i, a);
}
if (xf == b)
return i;
if (xf == b && a < 0)
return 1 / i;
else {
bgint = i;
lsint = i - 1;
for (j = 0; j < 1000000; j++) {
x = ((b - power(lsint, ABS(a))) / (xf - power(lsint, ABS(a)))) * (bgint - lsint);
w = lsint + x;
delta = w - wtemp;
if (ABS(delta) < eps) {
return w;
} else {
lsint += x;
wtemp = w;
}
}
if (a > 0)
return w;
else
return 1 / w;
}
}
其中power()
是我写的函数:
double power(double a, double b) {
int countPower;
double result;
if (b >= 0) {
for (result = 1, countPower = 0; countPower < (int)b; countPower++)
result *= a;
} else {
for (result = 1, countPower = (int)-b; countPower > 0; countPower--)
result /= a;
}
return result;
}
事情是这样的:如果做 nroot(2, 10000000000) /* 10.000.000.000 */
我得到 -1.000002
.
我不明白这个结果是从哪里来的,因为如果我这样做 nroot(2, 1000000000) /* 1.000.000.000 */
,我会得到 31622.776599
,这是正确的结果。
如有任何评论,我们将不胜感激。
你的 power
功能似乎没问题。
您的问题来自这一行:
while(xf<(int)b)
您将 b
转换为一个整数,默认情况下肯定是 32 位,其最大值约为 2e9
(参见 INT_MAX
)。
因此,当 b
结束时 INT_MAX
,您的代码将不再有效。
要更正问题,只需删除强制转换,代码变为:
while (xf < b)
{
i++;
xf = power(i, a);
}
您的代码有未定义的行为,因为 xf
在 while (xf < (int)b) {
中未初始化。
它在某些情况下只是偶然地起作用...此外,如果 b
大于 INT_MAX
,将 b
转换为 (int)
是不必要的并且会适得其反,大约32 位系统上为 20 亿。请注意 i
也未初始化。您可能应该在此循环之前将 i
和 xf
都设置为 1
:
i = xf = 1;
while (xf < b) {
i++;
xf = power(i, a);
}
我正在尝试编写自己的代码来计算数字的 n 次方根。它适用于数量级为 109 的数字,但对于更大的数字,它给了我奇怪的东西。
double nroot(double a, double b) {
int j;
double i, wtemp, w, xf, x, bgint, lsint, eps = 0.000000001, delta;
if (b == 0)
return 0;
if (a == 1)
return b;
while (xf < (int)b) {
i++;
xf = power(i, a);
}
if (xf == b)
return i;
if (xf == b && a < 0)
return 1 / i;
else {
bgint = i;
lsint = i - 1;
for (j = 0; j < 1000000; j++) {
x = ((b - power(lsint, ABS(a))) / (xf - power(lsint, ABS(a)))) * (bgint - lsint);
w = lsint + x;
delta = w - wtemp;
if (ABS(delta) < eps) {
return w;
} else {
lsint += x;
wtemp = w;
}
}
if (a > 0)
return w;
else
return 1 / w;
}
}
其中power()
是我写的函数:
double power(double a, double b) {
int countPower;
double result;
if (b >= 0) {
for (result = 1, countPower = 0; countPower < (int)b; countPower++)
result *= a;
} else {
for (result = 1, countPower = (int)-b; countPower > 0; countPower--)
result /= a;
}
return result;
}
事情是这样的:如果做 nroot(2, 10000000000) /* 10.000.000.000 */
我得到 -1.000002
.
我不明白这个结果是从哪里来的,因为如果我这样做 nroot(2, 1000000000) /* 1.000.000.000 */
,我会得到 31622.776599
,这是正确的结果。
如有任何评论,我们将不胜感激。
你的 power
功能似乎没问题。
您的问题来自这一行:
while(xf<(int)b)
您将 b
转换为一个整数,默认情况下肯定是 32 位,其最大值约为 2e9
(参见 INT_MAX
)。
因此,当 b
结束时 INT_MAX
,您的代码将不再有效。
要更正问题,只需删除强制转换,代码变为:
while (xf < b)
{
i++;
xf = power(i, a);
}
您的代码有未定义的行为,因为 xf
在 while (xf < (int)b) {
中未初始化。
它在某些情况下只是偶然地起作用...此外,如果 b
大于 INT_MAX
,将 b
转换为 (int)
是不必要的并且会适得其反,大约32 位系统上为 20 亿。请注意 i
也未初始化。您可能应该在此循环之前将 i
和 xf
都设置为 1
:
i = xf = 1;
while (xf < b) {
i++;
xf = power(i, a);
}