2

I want to know the range of numbers which can be used for 'a' and 'b' without getting error.(ie. the output should also give correct value. )

#include <stdio.h>
#include <stdlib.h>

int sum(int * , int *);

int main()
{
unsigned int a= 10;
int b = -30,c;

c=sum(&a,&b);
printf("sum of %d and %d is %d",a,b,c);

return 0;
}

int sum(int *p , int *q)
{
return *p+*q;
};

I gave a signed number to the variable 'a', which is declared as unsigned integer and '-30' for variable 'b'. I got correct output for values of a greater than -2147483618(-2147483617,-2147483616 and so on). But i got positive values for a=-2147483619 onwards. Why is it so? Please help me out.

Achilles
  • 21
  • 2

3 Answers3

3

I don't think the internal representation of unsigned and signed integers is defined in the standard. (Especially since even the size of an 'int' can vary.) So your behavior will be undefined. It may be consistent on a particular system, but it may very well not transfer to another system/compiler.

Jiminion
  • 5,080
  • 1
  • 31
  • 54
0

As mentioned in the comments, the issue is that you are going over the range of the integer and unsigned integer ranges. This is the reason why you are getting an unexpected result. From this link:

int 2 bytes: from -32,768 to 32,767
int 4 bytes: from -2,147,483,648 to 2,147,483,647
unsigned int 2 bytes: from 0 to 65,535
unsigned int 4 bytes: from 0 to 4,294,967,295

In your case, when b (or the result of the addition of a and b) has a value lower than -2,147,483,648 or higher than 2,147,483,647, it overflows and it will have an undefined behavior (for example: what you are getting, a positive value for additions of two negative values).

You can read more about integer overflow and how C handles it on this Wikipedia page.

Alvaro Montoro
  • 28,081
  • 7
  • 57
  • 86
0

For int, the only portable solution involves using INT_MIN and INT_MAX as int overflow is undefined behavior. So to find the range of int, print these two.

As overflow with unsigned is well define, the maximum unsigned is always:

unsigned maxu = -1;  // -1 converts to the maximum unsigned
unsigned minu = 0;

So given unsigned_a + int_b --> int_c, something like the following would detect overflow. The 2nd half likely has a problem TBD.

bool SumWithOverflowDetect(unsigned a, int b, int *c) {
  if (b >= 0) {
    if (INT_MAX - b < a) return true;
    *c = a + b;
  } else {
    unsigned sum = a + b; // converts b to unsigned before the addition
    if (sum > a) return true;
    if (sum > INT_MAX) return true;
    *c = sum;
  }
  return false;
}

An easier way to detect overflow uses int2x

bool SumWithOverflowDetect2(unsigned a, int b, int *c) {
  // int2x is some type wider than int/unsigned
  int2x sum = (int2x) a + (int2x) b;
  if (sum < INT_MIN || sum > INT_MAX) return true;
  *c = (int) sum;
  return false;
}
Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256