在Java中获得登录的最快方法?

在Java中获得登录的最快方法?,java,optimization,logic,bit-manipulation,Java,Optimization,Logic,Bit Manipulation,我想把float值的符号作为int值-1或1 避免条件句在降低计算成本方面总是一个好主意。例如,我能想到的一种方法是使用快速的位移位来获取符号: 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 fo

我想把
float
值的符号作为
int
值-1或1

避免条件句在降低计算成本方面总是一个好主意。例如,我能想到的一种方法是使用快速的
位移位来获取符号:

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.
float a=。。。;
int符号=a>>31//0表示pos,1表示neg
符号=~符号//1表示pos,0表示neg

sign=sign>31)您不简单使用的任何原因:

int sign = (int) Math.signum(a); //1 cast for floating-points, 2 for Integer types
此外,大多数数字实现都有一个signum方法,它接受该类型的原语并返回int,因此可以避免强制转换以获得额外的性能

int sign1 = Integer.signum(12); //no casting
int sign2 = Long.signum(-24l); //no casting
它将返回+1/0/-1,并且经过优化以提供良好的性能

int sign1 = Integer.signum(12); //no casting
int sign2 = Long.signum(-24l); //no casting
作为参考,你可以看看。相关位为:

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

只有在绝对必要的情况下,才应该尝试使用难以理解的优化

问题在于

int sign = Math.signum(a);
如果0.0==a,则可能返回0

但您应该尽可能依赖现有的库函数,以使代码易于阅读/理解

如果您希望0.0==a等于1,那么这个呢:

int sign = (0>a)?-1:1;

如果只需要浮点值中的IEEE 754符号位,可以使用:

/**
 * Gets the sign bit of a floating point value
 */
public static int signBit(float f) {
    return (Float.floatToIntBits(f)>>>31);
}
这是非常快的,并且具有没有分支的优点。我认为这是在JVM上可以达到的最快速度


但要确保它是你想要的!特别要注意特殊情况,例如,从技术上讲,NaN可以有0或1符号位。

我不知道这一点。关于性能,您可能也是对的。+1它已经过优化,可以处理诸如整型.signum()和Long.signum()等情况?您不必强制转换到关联类型。@DandreAllison确实有一个很好的观点,尽管OP正在寻找浮点的符号,并且没有
float.signum()
方法…@assylias奇怪的是
float
没有提供
signum
Math
提供时。您的公式为
float.NaN
返回+1。这可能是可以接受的。