C:在无符号变量的情况下执行带符号变量的签名比较

时间:2010-11-01 12:47:10

标签: c casting comparison unsigned signed

我想要一个具有以下签名的函数:

bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b);

如果1中存储的位的2的补码视图大于a中存储的位的2的补码视图,则其输出应为b。否则输出应为0。例如:

signed_a_greater_than_signed_b(0b10000000,any number) => 0
signed_a_greater_than_signed_b(0b01111111,any number other than 0b01111111) => 1
signed_a_greater_than_signed_b(0b00000000,0b00000001) => 0
signed_a_greater_than_signed_b(0b00000000,0b11111111) => 1
signed_a_greater_than_signed_b(0b00000000,0b00000000) => 0

该函数没有任何隐式/显式转换(因为这些转换是 实现定义,因此不可移植)

一个这样的实现是:

bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b)
{
    // if 'signed' a is positive then 
    //     return 1 if a is greater than b or b is negative
    // otherwise, if 'signed' a is negative then 
    //     return 1 if a is greater than b and b is negative
    if (a <= 0b01111111) return ((b < a) || (b > 0x01111111));
    else                 return ((b < a) && (b > 0x01111111));
}

你能建议一个使用算术而不是条件来执行这个计算的实现吗?如果你必须

,你可以使用一个条件

在比较中使用混合的un / signed变量和在C中使用算术是灾难的一个方法。这个函数是如何规避问题的一个例子。

我认为签名变量比较背后的程序集与我想要实现的功能类似(在不支持签名比较的架构上)

2 个答案:

答案 0 :(得分:6)

假设2的补充:

return (a^signbit) > (b^signbit);

其中signbit显然是表示的MSB。

答案 1 :(得分:0)

  如果你必须

,你可以使用一个条件

您已经有一个仅使用一个条件的解决方案。 ;)

由于您希望使用算术运算而不是条件运算,我认为目标是速度。使用查找表甚至比算术更快。因为您使用的是8位字符,所以查找表意味着没有过度杀伤:您甚至不需要大小为256x256的表。表大小为256非常适合存储a的每个值的限制,表示值b可能必须导致为真(或假)。每个函数调用只需要执行一个表查找(a - > limit)和一个比较(limit&lt;&gt; b)。