0

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

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

它的输出应该是1iff 中存储的位a的 2 补码视图大于存储在 中的位的 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));
}

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

在比较和 C 中的算术中混合使用 un/signed 变量是灾难的根源。此功能是如何规避问题的示例。

我想有符号变量比较背后的程序集类似于我想要实现的函数(在不支持有符号比较的架构上)

4

2 回答 2

6

假设 2 的补码:

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

其中signbit显然是表示的 MSB。

于 2010-11-01T13:38:51.963 回答
0

如果必须,您可以使用一种条件

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

由于您希望进行算术运算而不是条件运算,因此我假设目标是速度。而且使用查找表比算术还要快。因为您使用的是 8 位字符,所以查找表并不意味着多余:您甚至不需要 256x256 大小的表。256 的表大小完全足以存储每个值的限制,以a指示值b可能必须导致真(或假)。每个函数调用只需要执行一次查表(a-> limit)和一次比较(limit<> b)。

于 2010-11-01T13:12:21.683 回答