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

ran*_*guy 0 c comparison unsigned signed casting

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

bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b);
Run Code Online (Sandbox Code Playgroud)

它的输出应该是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
Run Code Online (Sandbox Code Playgroud)

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

一个这样的实现是:

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));
}
Run Code Online (Sandbox Code Playgroud)

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

在比较中使用混合的未签名变量和在C中使用算术是灾难的一个方法.此函数是如何规避问题的示例.

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

APr*_*mer 6

假设2的补码:

return (a^signbit) > (b^signbit);
Run Code Online (Sandbox Code Playgroud)

signbit显然,表示的MSB 在哪里.