Math.pow()
,pow()
,不管它叫什么,很多语言(和计算器(都有一些内置函数来计算浮点数(或双精度(的x=a^b。有一种特殊情况是 a 是负数,b 不是整数。有些会返回NaN
,有些会给出复杂的结果(咳咳 Python(。但有些实际上能够给出真正的结果,所以我想知道的是怎么做。解释我的困惑:
假设 b 是有理数:b=c/d。现在我们看看c和d的奇偶性:
-
d 是偶数:没有实数 x -> NaN 或误差
-
D 为奇数,C 为偶数:正 x
-
D 为奇数,C 为奇数:负 x
浮点数以特定格式存储,这意味着如果从字面上解释,它将始终是偶数 d(实际上是 2 的幂(。没有办法知道c和d的真实奇偶校验,因为该信息在计算中丢失了。它只需要猜测。
所以我猜测它在做什么 - 它试图找到一个接近 b 的有理 c/d,奇数 d,c 和 d 都小于某个阈值 t.较小的 t 意味着它可以更确定它是正确的,但它适用于更少的数字。如果成功,它将使用 c 的奇偶校验。否则,它假装 d 是偶数。毕竟,浮点数可以是任何东西,数学库不想通过假设它是理性的来给出可能错误的结果,而它可能不是。
不过这只是我的猜测。如果有人真的看过这些幂函数之一(或规范,这同样好(中的代码,并且可以提供洞察力,那就太好了。
首先看到: 负指数平方的幂
现在让我们假设情况x^y
,其中x<0
和y
不是整数。如果您使用
x^y = exp2(y*log2(x))
然后你;受log2
定义范围的限制,因此NaN
或|x|^y
。如果你想要更好的东西,你可以尝试y
这种形式:
y = a/b
其中a,b
是整数。如果可能(或者如果应用了舍入(,则将问题更改为:
x^y = (x^a)^(1/b)
所以现在你可以处理更多情况(完全按照你的建议(:
如果
a
是偶数,则次级结果不再是负数x^a>=0
如此(x^a)^(1/b)>=0
如果两个
a,b
都是奇数,则结果为阴性否则结果是
NaN
或改用|x|^y
现在回到你的float
问题,数字总是这样:
y = mantissa*exp2(exponent)
所以是的b
是偶数(除非exponent!=0
这意味着数字是整数(。由于mantissa
存储为整数,因此您可以通过检查其LSB来获取其奇偶校验。不要忘记,在floats
中,MSB丢失了,除非存在非规范化或Nan/Inf
数字等特殊情况,否则应始终1
如果你准备作弊,以下是你可以对任何权力提出否定的方法:
x^(b/c)=x^(2b/2c)=(x^2b)^(1/2c)
x^2b
是积极的,所以取 2c 根没有问题