获得Java签约的最快方式?

我想将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. 

或者更简洁:

 int sign = (~(a >> 31) << 1) - 1; 
  1. 这看起来像是一个好方法吗?
  2. 鉴于字节顺序问题(MSB持有标志),这是否适用于所有平台?

您不能简单使用的任何理由:

 int sign = (int) Math.signum(a); //1 cast for floating-points, 2 for Integer types 

此外,大多数Number实现都有一个signum方法,它采用该类型的原语并返回一个int,因此您可以避免强制转换以获得额外的性能。

 int sign1 = Integer.signum(12); //no casting int sign2 = Long.signum(-24l); //no casting 

它将返回+1 / 0 / -1并且已经过优化以提供良好的性能。

作为参考,您可以查看openJDK中的实现 。 相关位是:

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

如果您只想要浮点值的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个符号位。

如果绝对必要,您应该尽量使用难以阅读/理解优化。

这个问题

 int sign = Math.signum(a); 

如果0.0 == a,它可能会返回0

但是,您应该尽可能依赖现有的库函数来保持代码易于阅读/理解。

如果你想要1代表0.0 ==那么这个:

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