在C/C++中是否有一种好的快速方法来测试多个变量是包含所有正值还是所有负值?
假设要测试5个变量:
变式1
int test(int a[5]) {
if (a[0] < 0 && a[1] < 0 && a[2] < 0 && a[3] < 0 && a[4] < 0) {
return -1;
} else if (a[0] > 0 && a[1] > 0 && a[2] > 0 && a[3] > 0 && a[4] > 0) {
return 1;
} else {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
变体2
int test(int a[5]) {
unsigned int mask = 0;
mask |= (a[0] >> numeric_limits<int>::digits) << 1;
mask |= (a[1] >> numeric_limits<int>::digits) << 2;
mask |= (a[2] >> numeric_limits<int>::digits) << 3;
mask |= (a[3] >> numeric_limits<int>::digits) << 4;
mask |= (a[4] >> numeric_limits<int>::digits) << 5;
if (mask == 0) {
return 1;
} else if (mask == (1 << 5) - 1) {
return -1;
} else {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
变式2a
int test(int a[5]) {
unsigned int mask = 0;
for (int i = 0; i < 5; i++) {
mask <<= 1;
mask |= a[i] >> numeric_limits<int>::digits;
}
if (mask == 0) {
return 1;
} else if (mask == (1 << 5) - 1) {
return -1;
} else {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
我应该选择什么版本?使用变体2/2a超过1是否有任何优势?还是有更好/更快/更清洁的方式?
我认为你的问题以及你所寻找的不同意.您询问如何检测它们是否已签名或未签名,但看起来您的意思是如何测试它们是正面还是负面.
对所有负面的快速测试:
if ((a[0]&a[1]&a[2]&a[3]&a[4])<0)
Run Code Online (Sandbox Code Playgroud)
和所有非负(> = 0):
if ((a[0]|a[1]|a[2]|a[3]|a[4])>=0)
Run Code Online (Sandbox Code Playgroud)
我想不出一个好方法来测试它们都是严格正面(不是零),但应该有一个.
请注意,这些测试对于二进制补码系统(您想要关注的现实世界中的任何内容)都是正确且可移植的,但对于补码或符号幅度而言,它们略有错误.如果你真的在乎,它们可能会被修复.
我猜你的意思是消极/积极,(联合国)签署意味着是否存在一个标志.这适用于任何可迭代的(假设您算作0正数):
template <class T>
bool allpos(const T start, const T end) {
T it;
for (it = start; it != end; it++) {
if (*it < 0) return false;
}
return true;
}
// usage
int a[5] = {-5, 3, 1, 0, 4};
bool ispos = allpos(a, a + 5);
Run Code Online (Sandbox Code Playgroud)
这可能不是绝对极其超级最快的方法,但它确实可读且非常快.优化这个是不值得的.