一种更通用的方式(正如人们所说,您需要补偿Math.Sign()
返回 0):
int myNum = -4;
int sign = Math.Sign(myNum);
myNum += 8 / 2 % 4; //some operation
myNum = Math.Abs(myNum) * sign;
一种有趣、快速但不可读的整数方法,不受该Math.Sign()
问题的影响:
int origNum = -4;
int newNum = origNum + (8 / 2 % 4); //some operation
int signMask = (origNum ^ newNum) >> 31; // flip the sign of newNum if origNum
newNum = (newNum ^ signMask) - signMask; // and newNum have different signs.
或者对于浮点类型,您可以屏蔽符号位,因为它们符合 IEEE 754。如果 JIT 对此很智能,它将产生一些非常有效的 SSE:
double myNum = -4.0;
long sign = GetSign(myNum);
myNum += 8.0 / 2.0 % 4.0; //some operation
myNum = SetSign(myNum, sign);
static long GetSign(double x)
{
return BitConverter.DoubleToInt64Bits(x) & signMask;
}
static double SetSign(double x, long sign)
{
return BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(x) & ~signMask | sign);
}
const long signMask = unchecked((long)(1UL << 63));