Please explain this code to me. Its about saturating addition. Especially the fu
ID: 3753988 • Letter: P
Question
Please explain this code to me. Its about saturating addition. Especially the function.
#include <stdio.h>
#include <limits.h>
/* Addition that saturates to TMin or TMax */
int saturating_add(int x, int y)
{
int sum = x + y;
int pos_overflow = !(x & INT_MIN) && !(y & INT_MIN) && (sum & INT_MIN);
int neg_overflow = (x & INT_MIN) && (y & INT_MIN) && !(sum & INT_MIN);
(!pos_overflow || (sum = INT_MAX)) && (!neg_overflow || (sum = INT_MIN));
return sum;
}
int main(int argc, char **argv)
{
printf("%d ", INT_MAX);
printf("%d ", INT_MIN);
printf("%d ", saturating_add(10, 10));
printf("%d ", saturating_add(INT_MAX, 10));
printf("%d ", saturating_add(INT_MAX, 0));
printf("%d ", saturating_add(INT_MIN, 10));
printf("%d ", saturating_add(INT_MIN, -2));
}
Explanation / Answer
Firstly Difference between & and && opertor should be known
Bitwise AND Operator (&) is Binary Operator because it operates on two operands and used for Bitwise AND operation.
For Eg:
int x=3;
if(x&1)
printf("ONE");
if(x&2)
printf("TWO");
In this statement value of x is 3 which is both bits are 1 (0011), condition (x&1) and (x&2) will be true and "ONETWO" both messages will print.
Logical AND (&&) is a Binary Operator which is used to check more than one conditions at a time and if all conditions are true result will be true
For Eg:
int x=10;
int y=20;
if(x==10 && y==20)
printf("TRUE");
else
printf("FALSE");
In this statement both conditions x==10 and y==20 are true, hence "TRUE" will print.
INT_MAX: 2147483647 (01111111111111111111111111111111)
INT_MIN: -2147483648 (10000000000000000000000000000000)
(i) printf("%d ", INT_MAX); --> returns value 2147483647
(ii) printf("%d ", INT_MIN); --> returns value -2147483648
(iii) printf("%d ", saturating_add(10, 10));
as per the code
x : 10 (1010)
y : 10 (1010)
sum : x+y = 20 (10100)
x & INT_MIN --> 1010 & 10000000000000000000000000000000 --> 0
y & INT_MIN --> 1010 & 10000000000000000000000000000000 --> 0
sum & INT_MIN --> 10100 & 10000000000000000000000000000000 --> 0
pos_overflow
!(0) && !(0) && (0) --> 1 && 1 && 0 --> 0
Therfore pos_overflow : 0
neg_overflow
(0) && (0) && !(0) --> 0 && 0 && 1 --> 0
Therfore neg_overflow : 0
(!pos_overflow || (sum = INT_MAX)) && (!neg_overflow || (sum = INT_MIN))
Here !pos_oveeflow is alreday 1 and similarly !neg_overflow also 1 so sum is not intialized with INT_MAX or INT_MIN
Therfore, saturating_add(10, 10): 20
(iv) printf("%d ", saturating_add(INT_MAX, 10));
As per the code
x : 2147483647 (01111111111111111111111111111111)
y : 10 (1010)
sum : x+y = -2147483639 (cant add more than Max value of Int hence unsigned value)
x & INT_MIN --> (01111111111111111111111111111111) & 10000000000000000000000000000000 --> 0
y & INT_MIN --> 1010 & 10000000000000000000000000000000 --> 0
sum & INT_MIN --> 1000000000000000000000000001010 & 10000000000000000000000000000000 --> 10000000000000000000000000000000
pos_overflow
!(0) && !(0) && (10000000000000000000000000000000) --> 1 && 1 && 10000000000000000000000000000000 --> 1
Therfore pos_overflow : 1
neg_overflow
(0) && (0) && !(10000000000000000000000000000000) --> 0 && 0 && 0 --> 0
Therfore neg_overflow : 0
(!pos_overflow || (sum = INT_MAX)) && (!neg_overflow || (sum = INT_MIN))
Here !pos_oveeflow is 0, so sum is intialized with INT_MAX (2147483647) and similarly !neg_overflow is 1 so sum is not intialized with INT_MIN
Therfore, saturating_add(INT_MAX, 10) --> returns value 2147483647
(v) printf("%d ", saturating_add(INT_MAX, 0)); --> returns value 2147483647
As per the code
x : 2147483647 (01111111111111111111111111111111)
y : 0 (0000)
sum : x+y = 2147483647
x & INT_MIN --> (01111111111111111111111111111111) & 10000000000000000000000000000000 --> 0
y & INT_MIN --> 0000 & 10000000000000000000000000000000 --> 0
sum & INT_MIN --> 01111111111111111111111111111111 & 10000000000000000000000000000000 --> 0
pos_overflow
!(0) && !(0) && (0) --> 1 && 1 && 0 --> 0
Therfore pos_overflow : 0
neg_overflow
(0) && (0) && !(0) --> 0 && 0 && 1 --> 1
Therfore neg_overflow : 0
(!pos_overflow || (sum = INT_MAX)) && (!neg_overflow || (sum = INT_MIN))
Here !pos_oveeflow is alreday 1 and similarly !neg_overflow also 1 so sum is not intialized with INT_MAX or INT_MIN
Therfore, saturating_add(INT_MAX, 0) --> returns value 2147483647
(vi) printf("%d ", saturating_add(INT_MIN, 10)); --> returns value -2147483638
As per the code
x : -2147483648 (10000000000000000000000000000000)
y : 10 (1010)
sum : x+y = -2147483638
x & INT_MIN --> (10000000000000000000000000000000) & 10000000000000000000000000000000 --> 10000000000000000000000000000000
y & INT_MIN --> 0000 & 10000000000000000000000000000000 --> 0
sum & INT_MIN --> 10000000000000000000000000000000 & 10000000000000000000000000000000 --> 10000000000000000000000000000000
pos_overflow
!(10000000000000000000000000000000) && !(0) && (010000000000000000000000000000000) --> 0 && 1 && 0 --> 0
Therfore pos_overflow : 0
neg_overflow
(10000000000000000000000000000000) && (0) && !(10000000000000000000000000000000) --> 0
Therfore neg_overflow : 0
(!pos_overflow || (sum = INT_MAX)) && (!neg_overflow || (sum = INT_MIN))
Here !pos_overflow is alreday 1 and similarly !neg_overflow also 1 so sum is not intialized with INT_MAX or INT_MIN
Therfore, saturating_add(INT_MIN, 10) --> returns value -2147483638
(vii) printf("%d ", saturating_add(INT_MIN, -2)); --> returns value -2147483648
As per the code
x : -2147483648 (10000000000000000000000000000000)
y : -2 (11111111111111111111111111111110)
sum : x+y = 2147483646 (01111111111111111111111111111110)
x & INT_MIN --> (10000000000000000000000000000000) & 10000000000000000000000000000000 --> 10000000000000000000000000000000
y & INT_MIN --> (11111111111111111111111111111110) & 10000000000000000000000000000000 --> 10000000000000000000000000000000
sum & INT_MIN --> 01111111111111111111111111111110 & 10000000000000000000000000000000 --> 0
pos_overflow
!(10000000000000000000000000000000) && !(10000000000000000000000000000000) && (0) --> 0 && 0 && 0 --> 0
Therfore pos_overflow : 0
neg_overflow
(10000000000000000000000000000000) && (10000000000000000000000000000000) && !(0) --> 1
Therfore neg_overflow : 1
(!pos_overflow || (sum = INT_MAX)) && (!neg_overflow || (sum = INT_MIN))
Here !pos_overflow is alreday 1 so sum is not intialized with INT_MAX and !neg_overflow is 0 so sum is intialized with INT_MIN
Therfore, saturating_add(INT_MIN, 10) --> returns value -2147483648