Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么math.pow天生就不能处理int?(地板/天花板也一样)_Java_Pow_Floor_Ceil - Fatal编程技术网

Java 为什么math.pow天生就不能处理int?(地板/天花板也一样)

Java 为什么math.pow天生就不能处理int?(地板/天花板也一样),java,pow,floor,ceil,Java,Pow,Floor,Ceil,我知道在Java(可能还有其他语言)中,Math.pow是在double上定义的,并返回double。我想知道,为什么编写Java的人实际上没有编写一个int-returning-pow(int,int)方法,在这位数学家看来,这个方法就像是一个新手程序员的脑门抽打(虽然很容易修复)遗漏。我忍不住想,有一些基于复杂的CS的幕后原因,我只是不知道,因为否则。。。嗯 在一个类似的主题中,ceil和floor按定义返回整数,那么它们为什么不返回整数呢 感谢大家帮助我理解这一点。它完全是次要的,但多年来

我知道在Java(可能还有其他语言)中,Math.pow是在double上定义的,并返回double。我想知道,为什么编写Java的人实际上没有编写一个int-returning-pow(int,int)方法,在这位数学家看来,这个方法就像是一个新手程序员的脑门抽打(虽然很容易修复)遗漏。我忍不住想,有一些基于复杂的CS的幕后原因,我只是不知道,因为否则。。。嗯

在一个类似的主题中,ceil和floor按定义返回整数,那么它们为什么不返回整数呢


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

原因在于(默认实现的JNI)的实现。CPU有一个求幂模块,该模块使用双倍作为输入和输出。既然您自己可以更好地控制它,为什么Java要为您转换它呢

对于地板和天花板,原因相同,但请注意:

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

因为
Math.pow
的结果甚至可能是
NaN
Infinity
,这取决于输入。

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


对于C语言,我认为这可以归结为CPU有专门的指令来对浮点数(而不是整数)执行Math.pow

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

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


浮点数可以表示
int
范围之外的整数。因此,如果您使用一个太大而无法放入
int
double
参数,对于
floor
来说,没有好的方法来处理它。

因为所有
int
s都可以被上抛到
double
而不会丢失,而且
double
上的
pow
函数的效率从数学角度来看并不低于
int
,如果整数大于231-1,则会溢出,如果大于264-1,则会溢出long。也不需要太多的时间就可以让它溢出

双精度是很好的,因为它们可以表示从~10-308到~10308的数字,精度为53位。可能存在一些边缘转换问题(例如,双精度中的下一个完整整数可能无法精确表示),但总的来说,与严格处理整数或长整数相比,您将获得更大的数字范围

在一个类似的主题中,ceil和floor按定义返回整数,那么它们为什么不返回整数呢


出于上述相同的原因-溢出。如果我有一个积分值,它大于我在长时间内所能表示的值,我就必须使用一些能表示它的东西。当我有一个小于我能在长时间内表示的值的整数值时,会发生类似的情况。

整数
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;
}

我认为这可以归结为CPU有专门的指令来对浮点数(而不是整数)进行Math.pow运算。对于
Math.pow
,整数(和long)可以转换为double,因此它们会自动处理。我认为它们只是在复制C的数学。h.@markspace:except,在我的编译器接受它之前,我似乎必须将任何int转换为double…我想到int的指数可以变得非常大。BigInteger确实提供指数。当你自己控制它的时候,为什么Java应该为你做任何事情?@djechlin好吧,在这种特殊情况下,它不会为你节省一行代码…在你给出的第二个示例中。。。整型铸造总是四舍五入吗?我认为它被截断了(所以(int)-4.5应该是-4)。不?凯蒂:是的,这两句话都不对。顶部的一个对正数有效,底部的一个对负数有效。@TavianBarnes啊,好的,这更有意义,谢谢,不是所有的都是JNI粘合的。请参阅默认实现。以
#round()
为例,计算效率不低,好吧,但可读性/打字效率高,不要为了5^7或其他什么而进行三次强制转换,这会节省很多…@Katie-是的,如果你必须有
int
的话,你必须进行结果强制转换,但是你不需要强制转换
int
参数-它们是自动向上强制转换的。如果你得到一个长的或者更大的结果呢
(int)Math.pow(10300)
即使它同样有效,也不意味着它同样准确。
// 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;
}