I add numbers, for example

0xAABB + 0xAABB (10101010_10111011 + 10101010_10111011 = 1 _0101010 1 _01110110)

How can I see if the selected bits overflowed. Particularly acute is the issue of overflow that occurs when adding the first byte of a number (0xBB).

Shifts do NOT apply. IF's NOT USED. MMX, SSE, etc. also no.

  • if (((0xAABB & 0xFF) + (0xAABB & 0xFF))> 0xFF) - there was an overflow in the low byte. Approximately the same can be written for the older. - Vladimir Martyanov
  • if you can't be used either, forgot to specify - neko69
  • then either assembler inserts, or compiler extensions — gcc.gnu.org/onlinedocs/gcc/… (this is for gcc). - KoVadim
  • the dude who asked me this puzzle says that he used only arithmetic. And assembler inserts are not simd instructions? - neko69
  • one
    @ neko69, where do you regularly have such impractical puzzles? - avp

2 answers 2

For unsigned addition, everything is simple - with unsigned addition, overflow occurs if the resulting amount is smaller (with unsigned comparison) of any of the operands. (Warren, Algorithmic Tricks)

So just look at the resulting byte (and two bytes) and compare. Sort of

unsigned short int sum(unsigned short int a, unsigned short int b) { unsigned short int s = a + b; if ((s&0xFF < a&0xFF) && (s&0xFF < b&0xFF)) cout << "Переполнение 8 бита" << endl; if ((s < a) && (s < b)) cout << "Переполнение 16 бита" << endl; return s; } 

Without if'ov - Urorren gives such options as (c - transfer, ie, the sum x + y + c is considered):

 (x&y)|((x|y)&~(x+y+c)) (x>>1)+(y>>1)+(((x&y)|((x|y)&c))&1) 

Well, in your case, c == 0, which simplifies the case ... Complicates the fact that the test should be considered separately from the summation, and separately for bytes and words.

Update:

 unsigned short int sum(unsigned short int x, unsigned short int y, bool&carry8, bool& carry16) { unsigned short int s = x+y; carry16 = ((x&y)|((x|y)&~s)); carry8 = carry16&0x80; carry16 = carry16&0x8000; return s; } 

Exhaustive brute force validation. There are no shifts, if'ov no.

Arranges?

  • and how to do this without if'ov and checks each byte separately? - neko69
  • @ neko69 And, yes, I repent, was inattentive, did not pay attention to the ban if. Now rummage ... Corrected the answer. - Harry
  • Shifts are also impossible - ixSci
  • @ neko69 Here, updated the answer, cited the code, checked it - it works. Is that okay? - Harry

You can do this:

 #include <iostream> int main() { auto first = 0xAABB; auto second = 0xAABB; auto leastByteSum = (first & 0xFF) + (second & 0xFF); bool leastByteOverflow = (leastByteSum & 0xFF) != leastByteSum; auto mostByteSum = (first & 0xFF00) + (second & 0xFF00); bool mostByteOverflow = (mostByteSum & 0xFFFF) != mostByteSum; std::cout << std::boolalpha << "Did least byte overflow: " << leastByteOverflow << "\n"; std::cout << std::boolalpha << "Did most byte overflow: " << mostByteOverflow << "\n"; } 

Or like this:

 auto first = 0xAABB; auto second = 0xAABB; auto ninthBit = 0b1'0000'0000; bool leastByteOverflow = ((first ^ second) & ninthBit) != ((first + second) & ninthBit); bool mostByteOverflow = ((first + second) & 0xFFFF) != (first + second); 

And here is another variation of the previous solution:

 auto first = 0xAABB; auto second = 0xAABB; auto ninthBit = 0b1'0000'0000; bool leastByteOverflow = (first ^ second) ^ (first + second) & ninthBit; bool mostByteOverflow = ((first + second) & 0x10000) > 0;