4

我知道在 Java(可能还有其他语言)中,Math.pow 是在双精度数上定义的并返回一个双精度数。我想知道为什么写 Java 的人到底没有写一个返回 int 的 pow(int, int) 方法,在这个数学家转为新手的程序员看来,这就像打额头一样(尽管显然很容易修复) 遗漏。我不禁想到,基于我不知道的复杂 CS 的一些幕后原因,否则……嗯?

在类似的主题上, ceil 和 floor根据定义返回整数,那么它们为什么不返回整数?

感谢大家帮助我理解这一点。这完全是次要的,但多年来一直困扰着我。

4

5 回答 5

4

java.lang.Math 只是 C 数学库所做的一个端口。

对于 C,我认为这归结为 CPU 有特殊指令来为浮点数(但不是整数)执行 Math.pow 的事实。

当然,该语言仍然可以添加一个int实现。事实上,BigInteger 有一个。这也是有道理的,因为pow往往会产生相当大的数字。

ceil 和 floor 根据定义返回整数,那么它们为什么不返回整数

浮点数可以表示范围之外的整数int。因此,如果您的double论点太大而无法放入 中int,则没有好的方法floor可以处理它。

于 2014-07-24T23:02:40.960 回答
2

从数学的角度来看,如果整数大于 2 31 -1,就会溢出整数,如果大于 2 64 -1 ,就会溢出 long 。溢出它也不需要太多。

双精度数很好,因为它们可以以 53 位精度表示从 ~10 -308到 ~10 308的数字。可能存在一些边缘转换问题(例如双精度中的下一个完整整数可能无法完全表示),但总的来说,与严格处理整数或多头。

在类似的主题上, ceil 和 floor 根据定义返回整数,那么它们为什么不返回整数?

出于上述相同的原因 - 溢出。如果我的整数值大于我在 long 中可以表示的值,我将不得不使用可以表示它的东西。当我的整数值小于我在 long 中可以表示的值时,也会发生类似的事情。

于 2014-07-24T23:21:49.483 回答
0

因为所有ints 都可以double无损失地向上转换为 a ,并且 a 上的pow函数的double效率不亚于a 上的函数int

于 2014-07-24T23:02:57.237 回答
0

pow()整数和浮点数的优化实现pow()有很大不同。C 的数学库可能是在考虑浮点协处理器的时候开发的。浮点运算的最佳实现是将数字移近 1(以强制更快地转换幂级数),然后将结果移回。对于整数幂,可以O(log(p))通过执行以下操作及时获得更准确的结果:

// p is a positive integer power set somewhere above, n is the number to raise to power p
int result = 1;
while( p != 0){
    if (p & 1){ 
        result *= n;
    }
    n = n*n; 
    p = p >> 1;
}
于 2017-11-30T10:07:33.187 回答
-1

原因在于Math.pow()(默认实现的JNI)的实现。CPU 有一个求幂模块,它可以作为输入和输出使用。当您自己可以更好地控制它时,为什么 Java 应该为您转换它?

对于 floor 和 ceil 原因相同,但请注意:

(int) Math.floor(d) == (int) d;   // d > 0
(int) Math.ceil(d) == -(int)(-d); // d < 0

对于大多数情况(不保证或超出Integer.MAX_VALUEInteger.MIN_VALUE)。

Java 留给你

(int) Math.pow(a,b)

因为结果Math.pow甚至可能是NaNInfinity取决于输入。

于 2014-07-24T23:02:16.827 回答