Предполагая, что у вас есть два 32-битных DWORD x и y, как вы можете определить, приведет ли их сумма к переполнению, но не прибегая к собственной сборке для проверки флага переноса. Я бы хотел что-нибудь с арифметическими или бинарными операторами. Я подумал, что могут быть некоторые методы тестирования битов, чтобы понять это. Спасибо
Обнаружение 32-битного двойного слова + двойное слово / C ++
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
С x = 5 и y = -5 вы получите истинное значение, несмотря на то, что это не переполнение, поскольку сумма меньше x.
- person Mario; 05.02.2012
@Mario: типы DWORD обычно беззнаковые.
- person dreamlax; 05.02.2012
@ Марио: это не совсем правильно.
-5
не является допустимым значением для целого числа без знака и становится 0xFFFFFFFB при присвоении DWORD. Итак, x + y = 0xFFFFFFFB + 5 = 0x100000000, и 32-битный результат 0 действительно является следствием переполнения.
- person kkm; 05.02.2012
Излишняя дополнительная проверка, отсутствие
const
(то есть не обучение хорошей практике). Однако я думаю, что было бы несправедливо, если бы я проголосовал против. Но, пожалуйста, исправьте. ;-) Ваше здоровье,
- person Cheers and hth. - Alf; 05.02.2012
@BicycleDude: Хорошо, я сам исправил твой код. Но, пожалуйста, прислушайтесь к комментариям о вещах, которые необходимо исправить. Не считайте само собой разумеющимся, что другие вмешаются и все исправят за вас.
- person Cheers and hth. - Alf; 05.02.2012
+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
Знаковое целочисленное переполнение - неопределенное поведение.
- person dreamlax; 05.02.2012
Поскольку поведение при переполнении целых чисел со знаком не определено, оптимизаторы компилятора могут и действительно сделать предположение, что ваш код не вызывает переполнения целых чисел со знаком. Дополнительную информацию см. здесь.
- person dreamlax; 05.02.2012
dreamlax правильный. поведение подписанного переполнения не определено в C ++, и ваш подход может зависеть не только от конкретной архитектуры ЦП, но и от режима, в котором он сейчас находится. Очень небезопасно и непереносимо.
- person kkm; 05.02.2012
+1 за то, что не добавил лишних проверок. примечание к @dreamlax: терминология OP с использованием DWORD подразумевает платформу Windows или, по крайней мере, платформу ПК.
- person Cheers and hth. - Alf; 05.02.2012
@ AlfP.Steinbach: операционная система или архитектура не имеют никакого значения для того факта, что некоторые компиляторы делают оптимизацию, исходя из предположения, что целочисленные типы со знаком не будут переполняться.
- person dreamlax; 05.02.2012
@ AlfP.Steinbach: Даже если предположить, что DWORD подразумевает Windows, это не определяет процессор. Windows Phone также будет использовать те же определения, и это работает на многих процессорах. Или вообще другой компилятор, как уже отмечалось Dreamlax.
- person kkm; 05.02.2012
@Mario: не
int
, подойдет только unsigned int
(или DWORD
). С int
s результат может быть неверным! Используйте это: DWORD overflowSum(DWORD a, DWORD b)
- person kkm; 05.02.2012
@ AlfP.Steinbach: Пожалуйста, не пытайтесь читать мои мысли. Я отвечаю здесь только потому, что. Что касается ссылки, вы можете прочитать это: stackoverflow.com/questions/3679047/
- person kkm; 05.02.2012
@kkm: это не ссылка, подтверждающая ваши утверждения. пожалуйста, прекратите распространять дезинформацию при переполнении стека. благодаря.
- person Cheers and hth. - Alf; 05.02.2012
@ AlfP.Steinbach: Вы заявили, что DWORD подразумевает [...] платформу ПК. Я только заметил, что это неверно, поскольку есть разновидности Windows, не работающие на платформе ПК, например, Windows Phone. Я не вижу, что в моем заявлении неверно. Если у вас есть ссылка, указывающая, что Windows Phone не работает под управлением Windows или что тип DWORD определен только в Windows SDK для платформы ПК, я был бы очень признателен, если бы вы ее разместили. Спасибо.
- person kkm; 05.02.2012
@kkm: цитирую вас: поведение подписанного переполнения не определено в C ++, и ваш подход может зависеть не только от конкретной архитектуры ЦП, но и от режима, в котором он сейчас находится. Очень небезопасно и непереносимо. это неверно для вопроса OP, который полагается на гарантии платформы. кроме того, вы дважды пытались ввести читателей в заблуждение относительно моих комментариев по этому поводу. пожалуйста, прекратите распространять дезинформацию при переполнении стека. благодаря.
- person Cheers and hth. - Alf; 06.02.2012
@ AlfP.Steinbach: Именно об этом я и говорил. Предыдущая версия кода Марио использовала целые числа, и это было как вне контекста вопроса, так и неопределенным в языке. пожалуйста, прекратите распространять дезинформацию при переполнении стека. благодаря.
- person kkm; 06.02.2012
@kkm:
int
в Windows (даже в 64-битной Windows) является 32-битным, дополнение до двух без треппинга. DWORD в Windows тоже 32-битный. Код полагается на это, а не на кроссплатформенные гарантии языкового стандарта. То есть ваши комментарии - это просто бессмысленная бессмысленная дезинформация. Пожалуйста, прекратите публиковать такую дезинформацию в переполнении стека.
- person Cheers and hth. - Alf; 06.02.2012
@ AlfP.Steinbach: Не могли бы вы еще раз изложить свою точку зрения? Правильно ли я понимаю, что вы говорите, что, несмотря на то, что стандарт C ++ не определяет поведение подписанного целочисленного переполнения, полагаться на его конкретное поведение является правильным для всех разновидностей Windows с любым компилятором ?
- person kkm; 06.02.2012