Побитовая проверка на переполнение со знаком, дающее неожиданные результаты - PullRequest
0 голосов
/ 22 сентября 2019

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

Один из тестов проходит два целых: -40 и 7. Продукт -280.Этот тест должен пройти, так как -280 находится в допустимых целочисленных границах, но моя функция сообщает мне, что это не удалось.Я замечаю, что каждый раз, когда я прохожу два целых, которые дают отрицательный продукт, я получаю один и тот же неверный результат.Код и тест ниже.Спасибо за любую помощь!

Я пытался распечатывать двоичные строки на каждом шаге, чтобы выяснить, почему конечное смещение вправо дает 1. Для этой программы условие должно взятьформа: hiproduct = (loproduct >> 31).

/* 
Function: Take two integers and determine if their product would produce an overflow within Integer boundaries using bit manipulation.
*/

bool tmult_ok(int x, int y) {
    long lx = (long)x;
    long ly = (long)y;
    long hiproduct = lx * ly; // These two are intentionally the same
    long loproduct = lx * ly; // and become different once masks apply
    printf("products: %d\n", hiproduct);

    long himask = 0xFFFFFFFF00000000;
    long lomask = 0x00000000FFFFFFFF;
    hiproduct = hiproduct & himask;
    loproduct = loproduct & lomask;

    printf("TMult result: %d, %d\n", hiproduct, loproduct);
    printf("Shifted loproduct: %d\n", (loproduct >> 31));
    return (hiproduct == (loproduct >> 31));
}

// Excerpt from main() in the test.c file -- not actual location!
int int1 = -40;
int int2 = 7;
assert(tmult_ok(int1, int2)); // True if no overflow would occur
printf("TMult Success Complete\n");

При запуске я получаю следующий вывод:

products: -280
TMult result: 0, -280
Shifted loproduct: 1
Assertion failed: (tmult_ok(int3, int4)), function main, file test.c, line 24.
Abort trap: 6

Ожидаемый результат состоит в том, что условие в операторе возвратаЗначение true, и, следовательно, вернет значение true.

1 Ответ

0 голосов
/ 22 сентября 2019

Значение -280 равно 0xfffffee8.Если вы сдвинете вправо на 31 из-за расширения знака, конечный результат будет 0xffffffff (-1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...