假设
我尝试了许多
n
和m
是正整数,并且 nm 在整数范围内,那么(int)pow(n,m)
会给出错误的答案吗?我尝试了许多
n
,其中 m=2
,到目前为止还没有得到错误的答案。n
和m
是正整数,并且 nm 在整数范围内,那么(int)pow(n,m)
会给出错误的答案吗?n
,其中 m=2
,到目前为止还没有得到错误的答案。 +
、 -
、 *
、 /
和 sqrt
的结果。自修订版以来,它建议一些其他函数返回正确舍入的结果,但所有这些建议都是可选的,很少有数学库实现了所有这些建议。pow
来计算整数的幂,建议(而且很容易)使用lround(pow(n, m))
而不是(long)(pow(n, m))
,这将把结果四舍五入到最接近的整数,而不是过于乐观地依赖误差为正。如果pow
在1ULP范围内,那么这应该可以给出正确的整数值,最高可达252(使用IEEE-754双精度浮点数)。在252和253之间,1ULP误差将为0.5,有时会将结果四舍五入到错误的整数。超过253,并非所有整数都可以表示为双精度浮点数。和毫无疑问还有很多其他的。
pow
是通过log
和exp
实现的,这些操作也需要按照IEEE规则“正确舍入”,请参见https://en.wikipedia.org/wiki/IEEE_floating_point#Recommended_operations。问题是,如果这些操作*被正确舍入*,答案是否会出错?当然,您不能假设每个C实现都遵守IEEE规则,但大多数现代实现都会这样做。 - Mark Ransomdouble
数字),那么最接近的数字是整数本身,从而验证了OP的假设是正确的。 - fuz在一个 int
有 64 位,double
也有 64 位的平台上,这可能不起作用,因为 pow()
的参数和结果的 double
没有足够的尾数来准确表示每个 64 位整数。在一个普通的平台上,其中 int
有 32 位,double
是一个 64 位 IEEE 754 浮点类型,你的假设是正确的。
pow
的("most common"等)实现是否保证始终返回calculated >= actual
? 中间浮点数舍入可能会导致略小于完整整数值,而(int)
转换将向下舍入。 - Jongware+
,-
,*
,/
)和返回浮点结果的<math.h>
和<complex.h>
库函数的精度是由实现定义的。” - rici__STDC_IEC_559__
保证了附录F中列出的特性,其中包括符合IEEE-754的1985版,而不是2008版。在1985年,只有+、-、*、/和sqrt需要正确舍入,即使在2008年,额外的函数也是可选的。尽管如此,我确实经常使用浮点数。但是当我转换为整数时,我会确保进行四舍五入而不是截断。 - rici这取决于您的整数和双精度浮点数的大小。
如果使用32位整数和64位IEEE 754双精度浮点数,则可以为所有可能的整数提供正确答案。
IEEE 754二进制64位浮点数(这是大多数现代计算机上双精度浮点数的常规表示)可以精确表示所有整数[0,2 ^ 53]。
exp(log(n)*m)
计算 pow(n, m),无法为许多整数返回正确的结果。 - phuclv
int
是一个64位整数,double
可能无法准确表示INT_MAX
。在这种情况下,(int)pow(INT_MAX, 1) != INT_MAX
。 - EOF