我需要在没有分支或布尔表达式的情况下实现以下函数:
uint8_t func(uint32_t num, uint8_t shl)
{
if (num >= (1 << shl))
{
return shl;
}
else
{
return 0;
}
}
我做的第一步是注意到else
部分很简单:
return num / (1 << shl);
当然,在if
部分执行此操作不一定会产生预期的结果。
所以我想我需要比num / (1 << shl)
更“聪明”的东西。
如果我能提出一个能给我1
或0
的表达,那么我就完成了。
是否有某种方法只使用算术/按位运算(即没有分支或布尔表达式)?
谢谢。
答案 0 :(得分:7)
您可以将条件视为一个布尔表达式,其计算结果为TRUE(1)或FALSE(0),因此您可以使用以下内容:
Excel::load('path to file\stlist.xlsx', function($reader) {
// reader methods
});
这段代码通常不是一个好主意,但在无分支约束下,它可以胜任。
答案 1 :(得分:4)
如果您想避免使用比较运算符,可以使用减法和位移来探测符号位:
uint8_t func(uint32_t num, uint8_t shl) {
return shl * (1 - ((num-(1<<shl)) >> (sizeof(num) * CHAR_BIT -1)));
}
答案 2 :(得分:3)
假设您的实现arithmetic shift(通常是这种情况)以及二进制补码算法,您可以利用符号位传播:
uint8_t func(uint32_t num, uint8_t shl)
{
return (-(int32_t)(num >> shl) >> 31) & shl;
}
可能转换为无分支x86汇编代码:
func(unsigned int, unsigned char):
mov eax, edi
mov ecx, esi
shr eax, cl
neg eax
sar eax, 31
and eax, esi
ret
主要思想是&
的左操作数是全部或全部为零,这意味着shl
的值保留或归零。
最棘手的部分是-(int32_t)(num >> shl)
。它建立在事实的基础上:
num / (1 << shl)
表达式与num >> shl
shl == 0
时,结果总是0
(即&
的左操作数的值是无意义的,因为它会被shl
丢弃1} 答案 3 :(得分:-3)
怎么样?
bool func( int32_t num, int8_t shl)
{
return (num>=(1<<shl));
}
Return 1 if x>=(1<<y)
Return 0 if x<(1<<y)