Eng*_*eer 29 java optimization logic bit-manipulation
我想将float值的符号作为int-1或1 的值.
避免条件总是降低计算成本的好主意.例如,我能想到的一种方法是使用快速bit-shift获取标志:
float a = ...;
int sign = a >> 31; //0 for pos, 1 for neg
sign = ~sign; //1 for pos, 0 for neg
sign = sign << 1; //2 for pos, 0 for neg
sign -= 1; //-1 for pos, 1 for neg -- perfect.
Run Code Online (Sandbox Code Playgroud)
或者更简洁:
int sign = (~(a >> 31) << 1) - 1;
Run Code Online (Sandbox Code Playgroud)
ass*_*ias 72
您不能简单使用的任何理由:
int sign = (int) Math.signum(a); //1 cast for floating-points, 2 for Integer types
Run Code Online (Sandbox Code Playgroud)
此外,大多数Number实现都有一个signum方法,它采用该类型的原语并返回一个int,因此您可以避免强制转换以获得额外的性能.
int sign1 = Integer.signum(12); //no casting
int sign2 = Long.signum(-24l); //no casting
Run Code Online (Sandbox Code Playgroud)
它将返回+1/0/-1并且已经过优化以提供良好的性能.
public static float signum(float f) {
return (f == 0.0f || isNaN(f)) ? f : copySign(1.0f, f);
}
public static boolean isNaN(float f) {
return (f != f);
}
public static float copySign(float magnitude, float sign) {
return rawCopySign(magnitude, (isNaN(sign) ? 1.0f : sign));
}
public static float rawCopySign(float magnitude, float sign) {
return Float.intBitsToFloat((Float.floatToRawIntBits(sign)
& (FloatConsts.SIGN_BIT_MASK))
| (Float.floatToRawIntBits(magnitude)
& (FloatConsts.EXP_BIT_MASK
| FloatConsts.SIGNIF_BIT_MASK)));
}
static class FloatConsts {
public static final int SIGN_BIT_MASK = -2147483648;
public static final int EXP_BIT_MASK = 2139095040;
public static final int SIGNIF_BIT_MASK = 8388607;
}
Run Code Online (Sandbox Code Playgroud)
如果您只想要浮点值的IEEE 754符号位,您可以使用:
/**
* Gets the sign bit of a floating point value
*/
public static int signBit(float f) {
return (Float.floatToIntBits(f)>>>31);
}
Run Code Online (Sandbox Code Playgroud)
这非常快,并且具有无分支的优点.我认为这是你在JVM上获得的最快速度.
但要确保它是你想要的!特别注意特殊情况,例如NaN在技术上可以有0或1个符号位.
如果绝对必要,您应该尽量使用难以阅读/理解优化.
这个问题
int sign = Math.signum(a);
Run Code Online (Sandbox Code Playgroud)
如果0.0 == a,它可能会返回0
但是,您应该尽可能依赖现有的库函数来保持代码易于阅读/理解.
如果你想1为0.0 ==那么这个:
int sign = (0>a)?-1:1;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
38774 次 |
| 最近记录: |