Overflow not beeing recognized, p is not printing warning [duplicate] - c

This question already has answers here:
How do I detect unsigned integer overflow?
(31 answers)
Closed 6 years ago.
I'm having a problem with my little c program.
I'm trying to print out a warning if an overflow occurs, I'm using the limits.h library to recognise an overflow with INT_MAX.
I guess the problem is in my if loop, but I can't really find the problem...
#include<stdio.h>
#include<limits.h>
int main()
{
int x = 1627964;
int y = 9;
for(int i=1; i<y; ++i){
x*= i; // x= x * i
printf("%d * %d \n",x , i+1);
if(x >= INT_MAX){
printf("An Overflow has occured!\n");
return 0;
break;
}
}
}
I think the overflow occurs after multiplying with 7:
1627964 * 2
3255928 * 3
9767784 * 4
39071136 * 5
195355680 * 6
1172134080 * 7
-384996032 * 8
1214999040 * 9
I can't really tell why the warning is not printed out...
Some help would be really appreciated, thanks :)

Only unsigned int has defined overflow behavior, signed int does not, so compiler could throw away half of your code if it detect it. Anyway in your code int never will be bigger than INT_MAX because on overflow it should be negative value.

If you try int max / i < x for the overflow ?

x == INT_MAX only tests if x is exactly equal to INT_MAX. Not less, not more, exactly equal.
What you should be testing for is signed integer overflow, which happens when you multiply by 1627964 by 8: if (x==INT_MAX || x < 0) - the sign bit gets incremented which makes your value negative.

Related

Please suggest an optimization in this code without using pow() function ? This question was asked to me in the interview [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 months ago.
Improve this question
when I give input as num=1, output should be 8
when I give input as num=2, output should be 16
when I give input as num=3, output should be 32
when I give input as num=4, output should be 64
and so on
Here is the code
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num,b;
scanf("%d",&num);
num=num+2;
b=pow(2,num);
printf("%d",b);
return 0;
}
I tried writing my own pow() function, but interviewer did not accept the solution.
You can use bit shifting.
Firstly, let's idenitfy the pattern (which you already have, it seems): for any given num, we should print out 2 to the power of num+2.
Consider that we are working in base 2. (Most) Computers nowadays store numbers in binary. Consider the binary representation of 1, 2, 4, 8 and 16.
1 = 0b00001
2 = 0b00010
4 = 0b00100
8 = 0b01000
16 = 0b10000
Notice that for each power of 2, there is only one bit set to 1. For increasing powers of 2, this bit moves to the left. With C, we can achieve getting something like this with the left shift operator in O(1), computationally faster than the O(log num) or O(num) implementations of pow as a library function and your own implementation of pow.
Instead of b=pow(2, num), you can try b=1<<num instead. This way, when num = 3 for example, the bit will be shifted three times to get 0b01000 = 8.
A straightforward approach can look for example the following way using the bitwise left shift operator.
Pay attention to that you should define the result when the value of num (that should be of unsigned integer type) is equal to 0.
#include <stdio.h>
unsigned long long f( unsigned int n )
{
return n == 0 ? 1 : 8llu << ( n - 1 );
}
int main( void )
{
const unsigned int N = 5;
for ( unsigned int i = 0; i < N; i++ )
{
printf( "%llu ", f( i ) );
}
putchar( '\n' );
}
The program output is
1 8 16 32 64
If the goal is to optimize the pow() call, you can't really replaces this with shift operations on an integer type; then there will be lost of precision for high values of n.
However, it is quite easy to write a pow2() function for integer input; It just need to set the exponent value of a double variable (assuming it’s in IEEE 754 format). Example code:
#include <stdio.h>
double pow2i(int n)
{
short s[4] = { 0 }; // IEEE 754
s[3] = (short)((n + 0x3FF) << 4 ); // writing the exponent value
return *(double*)&s;
}
double f(int n)
{
return pow2i(n+2);
}
int main()
{
for( int i = 1; i < 201; i++ )
printf("f(%d): %.0f\n",i,f(i));
return 0;
}

Why is integer conversion done this way? [duplicate]

This question already has answers here:
Unsigned values in C
(3 answers)
Closed 9 months ago.
I ran into an interesting scenario with integer conversion:
#include <stdio.h>
int main()
{
unsigned int x = 20;
unsigned int y = 40;
printf("%d\n", x - y);
printf("%d\n", (x - y) / 4);
}
~ % ./a.out
-20
1073741819
I wasn't expecting the 2nd result. Since x and y are both unsigned ints is the result of x - y unsigned (and in this case displayed as signed by printf)?
The things you are printing are indeed unsigned integers and you should print them with %u, but that does not explain the surprising result for the second number. The surprising result comes from an overflow occurring when you calculate x - y, since the result of that subtraction is negative and thus not representable as an unsigned int.
Unsigned overflow/underflow is not undefined behavior, so it's OK to have code like this in production if you know what you are doing.

Detecting unsigned overflow when accumulating variables [duplicate]

This question already has answers here:
How do I detect unsigned integer overflow?
(31 answers)
Closed 7 years ago.
I have two unsigned 32 bit integers, call them x and y. I want to periodically increment the two uint32's by seemingly random uint32 values. x and y will accumulate and I want them to continue to accumulate until they hit their limit, at which point I want them to start back at 0 + the value they would have had added had they not overflowed.
Assume the code looks like:
//This would be called, say every 5 seconds
void increment_vals(uint32_t *x, uint32_t *y, uint32_t x_inc, uint32_t y_inc)
{
*x += x_inc;
*y += y_inc;
if (x overflowed || y overflowed)
{
*x = x_inc;
*y = y_inc;
}
}
So basically my question is: how do I know when x OR y has overflowed and need to to be reset? Should I just store x and y before incrementing and if the result is less than the original value then it must have overflowed? Is that guaranteed?
Thanks.
You could check for overflow before incrementing:
if(x_inc > (MAXINT - *x)) {
//about to overflow
}
I suggest
uint32_t xx = *x + x_inc;
if (xx < *x)
*x = 0;
else *x = xx;
I found this document quite helpful and descriptive in answering my question, particularly page 172:
"For unsigned integers, if the sum is smaller than either operand,
an overflow has occurred."

Bitwise overflow checking in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write two functions that will check/prevent overflow in c (using only ! ~ | & ^ +) but cant get it. The first is will a certain twos compliment/signed int will fit in a certatin amount of bits: fitsB(int x, int n) where is the int and n is the size of bits to use. Also a function that will check to see if two ints will not overflow when added together: overflowInt(int x, int y). I can get it if they are unsigned ints but the negatives just make things harder for me. Anyone know how to?
There also is no casting and ints are always 32 bit
/*
* addOK - Determine if can compute x+y without overflow
* Example: addOK(0x80000000,0x80000000) = 0,
* addOK(0x80000000,0x70000000) = 1,
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int addOK(int x, int y) {
// Find the sign bit in each word
//if a and b have different signs, you cannot get overflow.
//if they are the same, check that a is different from c and b is different from c,
// if they are the same, then there was no overflow.
int z=x+y;
int a=x>>31;
int b=y>>31;
int c=z>>31;
return !!(a^b)|(!(a^c)&!(b^c));
}
x will fit in n bits if x < 2^(n-1).
The overflow question needs more information. Two ints will not overflow if you assign them to a long (or a double).
Using the above example (Adam Shiemke), you can find the maximum (positive) value and minimum value (negative) to get the range for n number of bits. 2^(n-1) (from Adam's example) and minus one for the maximum/positive number which can be represented in the n bits. For the minimum value, negate 2^(n-1) to get the minimum value x => -(2^(n-1)); (Note the >= not > for the minimum range). For example, for n = 4 bits, 2^(4-1) - 1 = 2^3 -1 = 7 so x <= 7 and x >= -8 = (-(2^(4-1)).
This assumes the initial input does not overflow a 32 bit quanity (Hopefully an error occurs in that condition) and the number of bits you are using is less then 32 (as you are adding 1 for the negative range and if you have 32 bits, it will overflow, see below for an explanation).
To determine if addition will overflow, if you have the maximum value, the x + y <= maximum value. By using algebra, we can get y <= maximum value - x. You can then compare the passed in value for y and if it does not meet the condition, the addition will overflow. For example if x is the maximumn value, then y <= 0, so y must be less then or equal to zero or the addition will overflow.

automatic type conversions [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
signed to unsigned conversions
A riddle (in C)
I am trying to understand why this program is not working
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
I came across this program when I was going through automatic type conversions in C.But I don't understand how conversions happen between signed and unsigned data types.Please explain.
Thank you,
Harish
sizeof() is of type unsigned, wile d is signed.
you check if d is smaller then an unsigned integer. Thus, the signed d is converted to unsinged.
But the bits representaion of the signed -1 when read as unsigned is greater then 2^31, and obviously greater then TOTAL_ELEMENTS-2, thus the condition is never met and you do not enter the for loop even once.
Look at this code snap, it might clear up things for you:
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned int x = 50;
int y = -1;
printf("x < y is actually %u < %u which yields %u\n", y,x,y < x);
return 0;
}
The above code prints:
x < y is actually 4294967295 < 50 which yields 0

Resources