我想知道是否有一种有效的方法将有符号整数转换为无符号短整型,其中负整数值在无符号短整型中被简单地设置为0(在C ANSI中)。我知道这可以通过一个简单的if语句来完成,如下所示:
int val1;
unsigned short val2;
val1=-5;
if(val1<0){
val2=0;
}else{
val2=(unsigned short) val1;
}
这种转换在我的程序中经常发生,而case val1
为负值的情况非常少见,所以每次都出现这种if语句似乎有点过分。
有没有更有效的方法来进行这种转换?
发布于 2014-05-09 10:33:42
通常有效的一件事是在表达式中直接使用布尔结果(0
或1
)。
而不是if
/else
构造,请尝试
val2 = val1 * (val1 > 0);
如果你追求的是绝对最佳的性能,别忘了用不同的编译器选项来测量不同的代码。
发布于 2014-05-09 09:17:51
如果您使用的是gcc,则可以使用内置函数为优化器提供有关整数(或布尔)表达式的可能结果的线索。
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
在下面的示例中,我们将分支标记为可能为真:
const char *home_dir ;
home_dir = getenv("HOME");
if (likely(home_dir))
printf("home directory: %s\n", home_dir);
else
perror("getenv");
根据您的代码执行以下操作:
#include <stdio.h>
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
int main(void)
{
int val1;
unsigned short val2;
val1 = -5;
if (unlikely(val1 < 0)) {
val2 = 0;
} else {
val2 = (unsigned short)val1;
}
return 0;
}
另一种使用指定宽度和按位运算符的方法:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
int32_t val1;
uint16_t val2;
val1 = -5;
val2 = (0xffff ^ (val1 >> 31)) & val1;
printf("%u\n", val2);
return 0;
}
发布于 2014-05-09 11:33:27
下面是几种不同的方法:
val2 = (unsigned short)val1 * (1+(val1>>(sizeof(val1)*8-1)));
val2 = (unsigned short)val1 * (1^((val1>>(sizeof(val1)*8-1))&1));
val2 = (unsigned short)val1 * (1^((unsigned)val1>>(sizeof(val1)*8-1)));
val2 = (unsigned short)val1 * (1-((unsigned)val1>>(sizeof(val1)*8-1)));
您可以通过将8
替换为CHAR_BIT
(在limits.h中定义)来使其更通用。
请注意,它不一定比简单的if/else
语句更有效。
https://stackoverflow.com/questions/23560626
复制相似问题