C: выполнение сравнения со знаком в беззнаковых переменных без приведения - PullRequest
0 голосов
/ 01 ноября 2010

Мне нужна функция со следующей сигнатурой:

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

функция не должна иметь никаких неявных / явных преобразований (так как эти преобразования определяются реализацией и, следовательно, не переносимы)

oneтакая реализация:

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, что является причиной катастрофы.эта функция является примером того, как обойти проблему.

Я полагаю, что сборка для сравнения знаковых переменных похожа на функцию, которую я хочу реализовать (на архитектурах, не поддерживающих знаковые сравнения)

Ответы [ 2 ]

6 голосов
/ 01 ноября 2010

Предполагая, что 2 дополняют:

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

, где signbit, очевидно, MSB представления.

0 голосов
/ 01 ноября 2010

вы можете использовать одно условие, если вам необходимо

У вас уже есть решение, использующее только одно условие.;)

Поскольку вы хотите выполнять арифметические операции, а не условные, я предполагаю, что целью является скорость.И использование справочной таблицы даже быстрее, чем арифметика.Поскольку вы используете 8-битные символы, справочная таблица не означает перерасхода: вам даже не нужна таблица размером 256x256.Размер таблицы 256 вполне достаточен для хранения предела для каждого значения a, указывающего, что значение (я) b может привести к значению true (или false).Каждый вызов функции должен выполнять только один просмотр таблицы (a -> limit) и одно сравнение (limit <> b).

...