有没有一种方法可以将一个整数转换为1,如果它大于等于1,而又不使用任何关系运算符?

15 浏览
0 Comments

有没有一种方法可以将一个整数转换为1,如果它大于等于1,而又不使用任何关系运算符?

在我的程序中,我有一个类似下面的语句,它在一个循环内部。\n

y = (x >= 1)? 0:1;

\n然而,我想避免使用任何关系运算符,因为我想使用SIMD指令,并不确定关系运算符是否与SIMD良好地配合使用。\n我想要类似下面的东西。\n

a = some_operation(x) // a将为1或0
y = 1 - a

\n其中some_operation将任何大于等于1的数字转换为1,并保持0为0。所以,我的问题是,是否有任何some_operation可以实现我的目的?

0
0 Comments

问题的出现原因是要将一个整数转换为1,如果它大于等于1,而不使用任何关系运算符。解决方法是使用二进制补码表示法。

根据问题描述,可以使用以下方法来解决这个问题:

1. 假设使用二进制补码表示法。

2. 定义一个整数变量x并赋值为任意整数,例如x = 42。

3. 定义一个整数变量test并赋值为x-1。

4. 使用位运算符和移位操作来判断test是否为负数或零。

5. 如果test的最高位为1,则表示整数为负数或零。

6. 如果test的最高位为0,则表示整数为正数。

以下是示例代码:

int x = 42; // 或任何整数

int test = x-1;

if(test & 1 << (CHAR_BIT * sizeof(int) -1))

{

// 整数为负数或零

}

else

{

// 整数为正数

}

需要注意的是,对于INT_MIN,此解决方法会引发未定义行为。一般来说,我们假设整数表示某个范围内的值。

以上就是解决这个问题的原因和方法。

0
0 Comments

有没有一种方法可以将整数转换为1,如果它大于等于1,而不使用任何关系运算符?

对于无符号整数,可以简单地执行以下操作:

unsigned int i = 42; // ... 或任何其他大于0的值。
unsigned int j = !!i; // j在这里为1。
i = 0;
j = !!i; // j在这里为0。

对于有符号整数,可以执行以下操作:

int i = ...
int j = !!(i * !((1 << ((CHAR_BITS * sizeof i) - 1)) & i));

上述代码行的结果是:

- 对于任何i < 1,结果为0

- 对于任何i >= 1,结果为1

!!x

只是一种复杂的方式来写

x?1:0

;它在编译器的角度来看并没有改变任何事情。有符号版本也会生成可怕的代码。我从来没有声称这是优雅的。不管怎样,是否

!!x

x?1:0

更加复杂,这取决于你如何看待它,无论如何,重点是它不会改变代码生成。再次强调:即使你在不同的语法下隐藏条件,条件语句仍然是条件语句。

显然,这比

>=

要复杂得多,所有主流的SIMD指令集都支持

>=

(对于有符号类型,只有x86直接支持;无符号比较需要进行范围转换,直到AVX-512)。但是,是的,对于有符号类型来说,手动实现会非常复杂,不像硬件比较那样类似于OF != SF。如果不考虑有符号溢出的可能性(例如来自INT_MIN),对

i - 1

进行逻辑右移即可。例如,

(i - 1U) >> 31

(或

CHAR_BIT * sizeof(i)-1

)可以将符号位作为0或1获取。

0
0 Comments

这个问题的出现是因为需要将一个整数转换为1,如果它大于等于1,而不使用任何关系运算符。

为了解决这个问题,可以使用位运算和逻辑运算符。下面是一个解决方案的示例代码:

#define INT_BITS (CHAR_BIT * sizeof(int))
int make_zero_or_one(int x) {
   return 1 - (((x-1) >> (INT_BITS-1)) & 1);
}

这个函数依赖于整数的最高有效位(Most Significant Bit)作为符号位。函数对于所有小于等于0的整数返回0,对于大于0的整数返回1。但是,如果`x-1`溢出,该函数将失败。

这个实现在编译后的代码中没有分支。

然而,这个实现对于`INT_MIN`会导致未定义行为(Undefined Behavior)。

尽管存在这个问题,但在大多数实际情况下,达到整数表示的限制通常会引发其他问题。

0