-1

I can only use the operations ! ~ & ^ ! + << >>, and I'm having trouble grasping overflow, could use any tips or help!

MisoSpoon
  • 9
  • 1
  • 3
    That is quite a nice homework question, but too broad as stack overflow is not a tutorial site. You have to solve yourself. Just that: Presuming you have to use signed integer types, you have to catch overflow **before** it occurs, otherwise all bets are off. So you have to check the operands in combination will go out of bounds. Hint: You have to use `limits.h` and think what "overflow" actually means. That is different for each operator. – too honest for this site Feb 05 '16 at 02:40
  • [How to detect integer overflow in C/C++?](http://stackoverflow.com/q/199333/995714) – phuclv Feb 05 '16 at 03:08
  • `>>` of negative integer values result in an _implementation-defined_ result. This greatly complicates using `>>` in a portable solution. – chux - Reinstate Monica Feb 05 '16 at 03:37
  • I don't think this question is duplicated, because of the condition "only use the operations ! ~ & ^ ! + << >>", it looks like a homework than a real work problem. – Holsety Feb 05 '16 at 04:38

3 Answers3

0

It depends on whether the numbers are signed or unsigned.

If both operands are unsigned, overflow will wrap back around to 0.

If one or both operands are signed, the behavior is implementation defined, however most implementations represent signed integers in 2's complement, so in those cases positive overflow will wrap around to the negative side, and negative overflow will wrap around to the positive side.

In the case of unsigned overflow, the result will be less than at least one operand, so you can test for it this way:

if ((x + y < x) || (x + y < y) {
    printf("overflow\n");
}

In the signed case, you first need to check whether both are positive (and check for negative wraparound) or both are negative (and check for positive wraparound):

if ((x > 0) && (y > 0) && ((x + y < x) || (x + y < y))) {
    printf("negative overflow\n");
}
if ((x < 0) && (y < 0) && ((x + y > x) || (x + y > y))) {
    printf("positive overflow\n");
}

As I mentioned before, the signed case is implementation defined, and the above will only work if signed integers are represented as 2's complement. In practice however, this will typically be the case.

This should give you an idea of how overflow works, although it doesn't use only the specific operators you mentioned. With this, you should be able to figure out how to use those other operators to achieve what the expressions above do.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • "An example of undefined behavior is the behavior on integer overflow." C11dr §3.4.3 3. This is the first example of undefined behavior in the C spec. It is not implementation defined, but UB.. – chux - Reinstate Monica Feb 05 '16 at 02:56
  • Disagree with "If one ... operands are signed, the behavior is implementation defined, " If one operand is `signed int` and the other is `unsigned int`, the `signed int` value will be converted to `unsigned int`, which is a well defined conversion. This leads to the well defined `unsigned` + `unsigned`. – chux - Reinstate Monica Feb 05 '16 at 03:13
  • `if ((x > 0) && (y > 0) && ((x + y < x) || (x + y < y))) {` is wrong - with optimizations turned up, your compiler ***will*** assume that `x + y < x` is always false given that `y > 0`. – user253751 Feb 05 '16 at 03:56
0

With signed integer math, unless you have access to the limits like INT_MAX INT_MIN, there is no answer that gets around undefined behavior.

#include <limits.h>

int is_overflow_add_signed(int a, int b) {
  // This uses -, so does not meet OP's goal.
  // Available as a guide
  return (a < 0) ? (b < INT_MIN - a) : (b > INT_MAX - a);
}

With unsigned math, simply see if the result "wrapped" around.

int is_overflow_add_unsigned(unsigned a, unsigned b) {
  return (a + b) < a;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
-1

As pointed by many peoples, it is not right for signed... So I changed it for unsigned first.

You need to calculate part by part.

Since you didn't tell us the data type, I assumed it is 4 byte unsigned data.

unsigned long x, unsigned long y;
// x = ...
// y = ...
unsigned long first_byte_x = (x & 0xFF000000) >> 24;
unsigned long first_byte_y = (y & 0xFF000000) >> 24;
unsigned long other_bytes_x = x & 0x00FFFFFF;
unsigned long other_bytes_y = y & 0x00FFFFFF;
unsigned long other_bytes_sum = other_bytes_x + other_bytes_y;
unsigned long carry = (other_bytes_sum & 0xFF000000) >> 24;
unsigned long first_byte_sum = first_byte_x + first_byte_y + carry;
if (first_byte_sum > 0xFF)
    // overflow
else
    // not overflow

If you can use mod(%), then it will be more simple.

*It looks like a homework so I hoped you considered enough before your asking...

Holsety
  • 103
  • 7