Обнаружение 32-битного двойного слова + двойное слово / C ++

Предполагая, что у вас есть два 32-битных DWORD x и y, как вы можете определить, приведет ли их сумма к переполнению, но не прибегая к собственной сборке для проверки флага переноса. Я бы хотел что-нибудь с арифметическими или бинарными операторами. Я подумал, что могут быть некоторые методы тестирования битов, чтобы понять это. Спасибо


person oldSkool    schedule 05.02.2012    source источник
comment
возможный дубликат переноса в x + y   -  person Oliver Charlesworth    schedule 05.02.2012


Ответы (2)


Почему бы не проверить сумму?

DWORD sum = x + y;
bool const overflow = (sum < x);
person Stephen Quan    schedule 05.02.2012
comment
С x = 5 и y = -5 вы получите истинное значение, несмотря на то, что это не переполнение, поскольку сумма меньше x. - person Mario; 05.02.2012
comment
@Mario: типы DWORD обычно беззнаковые. - person dreamlax; 05.02.2012
comment
@ Марио: это не совсем правильно. -5 не является допустимым значением для целого числа без знака и становится 0xFFFFFFFB при присвоении DWORD. Итак, x + y = 0xFFFFFFFB + 5 = 0x100000000, и 32-битный результат 0 действительно является следствием переполнения. - person kkm; 05.02.2012
comment
Излишняя дополнительная проверка, отсутствие const (то есть не обучение хорошей практике). Однако я думаю, что было бы несправедливо, если бы я проголосовал против. Но, пожалуйста, исправьте. ;-) Ваше здоровье, - person Cheers and hth. - Alf; 05.02.2012
comment
@BicycleDude: Хорошо, я сам исправил твой код. Но, пожалуйста, прислушайтесь к комментариям о вещах, которые необходимо исправить. Не считайте само собой разумеющимся, что другие вмешаются и все исправят за вас. - person Cheers and hth. - Alf; 05.02.2012
comment
+1 Thx Alf за снятие лишнего чека. Я был в восторге и только что вернулся. - person Stephen Quan; 05.02.2012

Должен в значительной степени сэкономить, чтобы предположить, скажите мне, пропустил ли я какой-либо случай (это не сработает в компиляторах, придерживающихся стандартов C ++ 98 или более новых):

int overflowSum(DWORD a, DWORD b) {
     return (b > 0) ? (a + b < a) : (a + b > a);
}

Если вы считаете свой DWORD беззнаковым, вы можете упростить его:

int overflowSum(DWORD a, DWROD b) {
    return a + b < a;
}
person Mario    schedule 05.02.2012
comment
Знаковое целочисленное переполнение - неопределенное поведение. - person dreamlax; 05.02.2012
comment
Поскольку поведение при переполнении целых чисел со знаком не определено, оптимизаторы компилятора могут и действительно сделать предположение, что ваш код не вызывает переполнения целых чисел со знаком. Дополнительную информацию см. здесь. - person dreamlax; 05.02.2012
comment
dreamlax правильный. поведение подписанного переполнения не определено в C ++, и ваш подход может зависеть не только от конкретной архитектуры ЦП, но и от режима, в котором он сейчас находится. Очень небезопасно и непереносимо. - person kkm; 05.02.2012
comment
+1 за то, что не добавил лишних проверок. примечание к @dreamlax: терминология OP с использованием DWORD подразумевает платформу Windows или, по крайней мере, платформу ПК. - person Cheers and hth. - Alf; 05.02.2012
comment
@ AlfP.Steinbach: операционная система или архитектура не имеют никакого значения для того факта, что некоторые компиляторы делают оптимизацию, исходя из предположения, что целочисленные типы со знаком не будут переполняться. - person dreamlax; 05.02.2012
comment
@ AlfP.Steinbach: Даже если предположить, что DWORD подразумевает Windows, это не определяет процессор. Windows Phone также будет использовать те же определения, и это работает на многих процессорах. Или вообще другой компилятор, как уже отмечалось Dreamlax. - person kkm; 05.02.2012
comment
@Mario: не int, подойдет только unsigned int (или DWORD). С ints результат может быть неверным! Используйте это: DWORD overflowSum(DWORD a, DWORD b) - person kkm; 05.02.2012
comment
@ AlfP.Steinbach: Пожалуйста, не пытайтесь читать мои мысли. Я отвечаю здесь только потому, что. Что касается ссылки, вы можете прочитать это: stackoverflow.com/questions/3679047/ - person kkm; 05.02.2012
comment
@kkm: это не ссылка, подтверждающая ваши утверждения. пожалуйста, прекратите распространять дезинформацию при переполнении стека. благодаря. - person Cheers and hth. - Alf; 05.02.2012
comment
@ AlfP.Steinbach: Вы заявили, что DWORD подразумевает [...] платформу ПК. Я только заметил, что это неверно, поскольку есть разновидности Windows, не работающие на платформе ПК, например, Windows Phone. Я не вижу, что в моем заявлении неверно. Если у вас есть ссылка, указывающая, что Windows Phone не работает под управлением Windows или что тип DWORD определен только в Windows SDK для платформы ПК, я был бы очень признателен, если бы вы ее разместили. Спасибо. - person kkm; 05.02.2012
comment
@kkm: цитирую вас: поведение подписанного переполнения не определено в C ++, и ваш подход может зависеть не только от конкретной архитектуры ЦП, но и от режима, в котором он сейчас находится. Очень небезопасно и непереносимо. это неверно для вопроса OP, который полагается на гарантии платформы. кроме того, вы дважды пытались ввести читателей в заблуждение относительно моих комментариев по этому поводу. пожалуйста, прекратите распространять дезинформацию при переполнении стека. благодаря. - person Cheers and hth. - Alf; 06.02.2012
comment
@ AlfP.Steinbach: Именно об этом я и говорил. Предыдущая версия кода Марио использовала целые числа, и это было как вне контекста вопроса, так и неопределенным в языке. пожалуйста, прекратите распространять дезинформацию при переполнении стека. благодаря. - person kkm; 06.02.2012
comment
@kkm: int в Windows (даже в 64-битной Windows) является 32-битным, дополнение до двух без треппинга. DWORD в Windows тоже 32-битный. Код полагается на это, а не на кроссплатформенные гарантии языкового стандарта. То есть ваши комментарии - это просто бессмысленная бессмысленная дезинформация. Пожалуйста, прекратите публиковать такую ​​дезинформацию в переполнении стека. - person Cheers and hth. - Alf; 06.02.2012
comment
@ AlfP.Steinbach: Не могли бы вы еще раз изложить свою точку зрения? Правильно ли я понимаю, что вы говорите, что, несмотря на то, что стандарт C ++ не определяет поведение подписанного целочисленного переполнения, полагаться на его конкретное поведение является правильным для всех разновидностей Windows с любым компилятором ? - person kkm; 06.02.2012