是否有一种快速的方法将 2.0
提升到某个浮点数幂 x
?我的意思是比使用 pow(2.0, x)
更快,最好能够与 AVX2 向量化。
对于整数,相应的方法是 1<<n
,但它只适用于整数 n
。
是否有一种快速的方法将 2.0
提升到某个浮点数幂 x
?我的意思是比使用 pow(2.0, x)
更快,最好能够与 AVX2 向量化。
对于整数,相应的方法是 1<<n
,但它只适用于整数 n
。
g++ -Ofast
可以将std::exp(x*std::log(2))
向量化,但奇怪的是却不能将std::exp2(x)
向量化。 - Marc Glisse对于整数次幂,您可以使用std::ldexp
函数:
double x = std::ldexp(1.0, k); // 2 to the power of k
这种方法比使用1<<k
和强制类型转换更好,因为它不会出现中间溢出,并且还支持负数幂。
x
,其中x
不是整数k
。 - Serge Rogatchk
是一个整数且无需检查是否超出范围,您可以通过位移和加法手动将偏置指数填入IEEE 754 double
中(通过偏置指数设置尾数),这样可以很好地进行自动向量化。 - Peter Cordesvector register x, y, z; /// x is our input, y will become our output
y = floor(x); /// 3 round toward -infinity
x -= y; /// 3 split integer and fraction
x *= ln(2); /// 5 ln(2) = 0.693147180559945...
y += x; /// summing the terms direct into the integer part
z = x * x; /// 5
y += z * (1/2); /// this is a single fma instruction but ...
z *= x; /// 5
y += z * (1/6); /// if your processor lacks it, the working register ...
z *= x; /// 5
y += z * (1/24); /// can be shared between the 4 parallel calculation chains
z *= x; /// 5
y += z * (1/120); /// the broadcasted constants can be shared too
z *= x; /// 5
y += z * (1/720); /// 8 I stopped here but you could easily carry on.
y *= 2^(mantissa bits); /// 5 8388608.0 for float,
/// 4503599627370496.0 for double
y = convert-float-to-int(y); /// 3 creates an integer where the original
/// integer part appears where the exponent bits
/// of a float value would be, and our added
/// fraction part becomes the mantissa, gaining
/// the 1.0 it was missing in the process
y = integer-addition(y, interpret-bits-as-integer(1.0)); /// 3
/// add the exponent bias to complete our result
/// this can be done as a float addition before
/// the convert-to-int, but bits of the precision
/// of the result get lost, because all of the
/// mantissa and exponent bits have to fit into the
/// mantissa before conversion
1<<n
并转换为双精度浮点数。如果这听起来很愚蠢,请原谅我 :-) - Malice