直接增加 double 的指数以乘以 2 的幂
Directly increase the exponent of a double in order to multiply by a power of two
我想增加基元的指数 double
d
,从而将其乘以 2 的幂,例如 2^64。
我可以做d *= math.pow(2, 64)
或者如果知道可以提前计算功率:d *= 18446744073709551616
.
但我想这是在做一些昂贵的操作,比如乘法,我们知道在这种情况下,所需要的只是指数的加法。
例如,如果可以在不转换的情况下将 double 解释为 long,我们可以这样做:(它不能那样工作)
long longFromD = d; // imagine the casting does not change any bits from d.
double dTimes2ToThe64 = longFromD + (64L << 52) // shifting 64 to be aligned with the exponent of d
这样我们就可以通过加法得到这个乘法。
使用@Johannes Kuhn 评论中的功能:
public static double multiplyByAPowerOfTwo(double d, int exponent) {
long dInterpretedAsLong = Double.doubleToLongBits(d);
dInterpretedAsLong += ((long) exponent) << 52; // add exponents
return Double.longBitsToDouble(dInterpretedAsLong)
}
@phuclv 评论的另一个选项,使用 HexadecimalFloatingPointLiteral
:
d *= 0x1.0p64;
对于这种方法,显然必须事先知道指数。这大概和d *= 18446744073709551616d;
一样,但是写起来优雅很多。
使用这种方法,我们有一个双倍乘法,希望它与指数相加一样有效(如果确实发生了乘法,它是一个)。
我想增加基元的指数 double
d
,从而将其乘以 2 的幂,例如 2^64。
我可以做d *= math.pow(2, 64)
或者如果知道可以提前计算功率:d *= 18446744073709551616
.
但我想这是在做一些昂贵的操作,比如乘法,我们知道在这种情况下,所需要的只是指数的加法。 例如,如果可以在不转换的情况下将 double 解释为 long,我们可以这样做:(它不能那样工作)
long longFromD = d; // imagine the casting does not change any bits from d.
double dTimes2ToThe64 = longFromD + (64L << 52) // shifting 64 to be aligned with the exponent of d
这样我们就可以通过加法得到这个乘法。
使用@Johannes Kuhn 评论中的功能:
public static double multiplyByAPowerOfTwo(double d, int exponent) {
long dInterpretedAsLong = Double.doubleToLongBits(d);
dInterpretedAsLong += ((long) exponent) << 52; // add exponents
return Double.longBitsToDouble(dInterpretedAsLong)
}
@phuclv 评论的另一个选项,使用 HexadecimalFloatingPointLiteral
:
d *= 0x1.0p64;
对于这种方法,显然必须事先知道指数。这大概和d *= 18446744073709551616d;
一样,但是写起来优雅很多。
使用这种方法,我们有一个双倍乘法,希望它与指数相加一样有效(如果确实发生了乘法,它是一个)。