我需要最有效的方法(在 cpu 周期内)来确定两个数字是否具有相同/不同的符号。但要注意的是,如果任一数字为零,我需要能够将其与具有相同/不同符号的数字区分开来(即。零被视为“第三个”符号)。以下代码与我需要的类似,但返回值可以是任何值,只要只有三个不同的返回值即可。
int foo(int x, int y) {
if (x * y > 0) return 1;
if (x * y < 0) return -1;
return 0;
}
对于我的特定问题,值在 [-6, 6] 范围内并且 X 保证不为 0。我找到了一个解决方案来确定两个数字是否具有相同的符号,并对其进行修改以获得以下解决方案。
return y? (((x^y) >= 0)? 1 : -1) : 0;
应该有一些比使用乘法、分支、比较更快得到结果的位操作/比较。
最佳答案
怎么样:
int foo(int x,int y)
{
// As suggested by Luther Blissett below in the comments.
// Increased the size of the array to 16x16.
// This allows for simpler optimization for the compiler
// Also use +8 rather +6 in the hopes that compiler optimization will be easier
// you never know (there may be some fancy trick.
static int sign[16][16] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1},
{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1},
{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1},
{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1},
{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1},
{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1},
{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1}
};
return sign[x+8][y+8];
}
这应该很快,因为没有会使处理器停止的分支。
使用 g++ -O3 -S:
__Z3fooii:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 12(%ebp), %edx
popl %ebp
sall $4, %eax
addl %edx, %eax
movl _ZZ3fooiiE4sign+544(,%eax,4), %eax
ret
关于c++ - c++中的三向条件确定两个数字的符号等价性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3297601/