我正在尝试编写一个函数的 C 代码,该函数接受一个整数从0to125并仅当它是整数( 1,2,3,4,5 )时才返回该整数的立方根,如果不是整数,0则返回。所以我写了这段代码:
unsigned int cubic(unsigned int n) {
if (n > 125)
return 0;
double root = pow(n, (1 / 3.));
double rem = (double)(roundf(root)) - root;
if (rem != 0)
return 0;
else
return roundf(root);
}
Run Code Online (Sandbox Code Playgroud)
此函数适用于除 number64和之外的所有情况125。在这些情况下,它返回的0不是这些数字的立方根,分别是4和5。有人可以向我解释为什么会发生这种情况吗?
由于1 / 3.无法准确地表示为浮点数,浮点计算pow(64, (1 / 3.))可能会产生一个非常接近 的数字4,但稍小或稍大,足以4与(double)(roundf(root)) - root不同0。
您可以通过以下方式解决此精度问题:
unsigned int cubic(unsigned int n) {
int root = (int)round(pow(n, 1 / 3.));
if (root * root * root == n)
return root;
else
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果您的系统上可用pow(n, 1 / 3.),您可以使用 代替cbrt(n),但精度问题可能仍然存在。
对于您的目标,迭代可能的整数根并检查似乎要简单得多:
unsigned int cubic(unsigned int n) {
for (unsigned int i = 1; i <= 5; i++) {
unsigned int i3 = i * i * i;
if (i3 == n)
return i;
if (i3 > n)
break;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
或者更明确地说:
unsigned int cubic(unsigned int n) {
switch (n) {
case 1 * 1 * 1: return 1;
case 2 * 2 * 2: return 2;
case 3 * 3 * 3: return 3;
case 4 * 4 * 4: return 4;
case 5 * 5 * 5: return 5;
default: return 0;
}
}
Run Code Online (Sandbox Code Playgroud)