Как @EugeneSh. наблюдает, перенос равен либо 0, либо 1. Более того, учитывая, что a
и b
имеют один и тот же тип unsigned, их сумма корректно определена, даже если арифметический результат превышает диапазон их типа. Кроме того, (C) результат суммы будет меньше, чем a
, и b
, когда происходит переполнение, и больше, в противном случае, поэтому мы можем использовать тот факт, что реляционные операции C оцениваются либо как 0, либо как 1, чтобы выразить бит переноса как
carry = (a + b) < a;
Это не требует никаких заголовков и не зависит от конкретной верхней границы или даже от того, что a
и b
имеют один и тот же тип. Пока оба имеют типы без знака, он правильно сообщает о том, переполняется ли сумма более широким из их типов или unsigned int
(в зависимости от того, что шире), что совпадает с их суммой, устанавливающей бит переноса. В качестве бонуса это выражается в виде самой суммы, что, я думаю, дает понять, что тестируется.
person
John Bollinger
schedule
07.05.2019
carry = __builtin_add_overflow(a, b, &res)
сохраняет младшие биты результата вres
и устанавливаетcarry
, если произошло переполнение. (На самом деле функция возвращаетbool
, то естьtrue
илиfalse
, поэтому присвоение ееcarry
даст 1 или 0.) - person Eric Postpischil   schedule 07.05.2019-1
беззнаковому целому числу? Это Undefined Behavior, и вы можете получить от этого что угодно, даже сбой программы. - person Luis Colorado   schedule 09.05.2019