我正试图编写一个函数的C代码,该函数需要从0
到125
的整数,只有当它是整数(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);
}
此函数在除数字64
和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;
}
如果系统上可用,可以使用cbrt(n)
代替pow(n, 1 / 3.)
,但是精度问题可能仍然存在。
对于您的目标,迭代可能的整数根并检查似乎要简单得多:
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;
}
或者更明确的:
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;
}
}