unsigned integer getting overflowed in c [duplicate] - c

This question already has answers here:
Unsigned int in C behaves negative
(8 answers)
Closed 8 years ago.
I wrote simple C program to find the maximum positive number I can reach using unsigned integer as given below. Size of integer on my machine is 4 bytes.
#include <stdio.h>
#include <math.h>
main()
{
unsigned int x = 1;
int i = 1;
for(; i <= 31; i++)
{
x = x * 2;
}
unsigned int y = pow(2, 31);
printf("%d\n", x);
printf("%d\n", y);
}
both x, y are getting overflowed and value as -2147483648. I thought it should not overflow because on the machines where sizeof(int) = 4 bytes, unsigned int range should be pow(2, 32) - 1. Can any one please let me know why this is getting overflowed?

You want to use %u for unsigned int:
printf("%u\n", x);
printf("%u\n", y);

Related

Even though I use % 1000000007 it still results on 0 [duplicate]

This question already has answers here:
Need help in mod 1000000007 questions
(4 answers)
Closed 4 years ago.
my goal on this code is to make exponential operations without pow().
It works for evey value a^b which b <= 30. I'm aware that I should be using x % 1000000007 to prevent integers overflows.
#include <stdio.h>
int main(void) {
int i, a, b, rst;
rst = 1;
scanf("%d %d", &a, &b);
for (i = 0; i < b; i++){
rst = rst * a;
if( b == 0){
rst = 1;
}
}
printf("%d\n", rst % 1000000007);
return 0;
}
Why does it returns a "0" for example on "2^40 % 1000000007" even though I'm using % 1000000007?
First, you don't need if statement in for loop.
Second, you are trying to stop integer overflow after it already happens. So you need to do it after every multiplication operation.
Third, you can use unsigned long long int instead of int, because int is machine dependent (may be 1000000007 is too big for int on your machine).
I guess this should work:
#include <stdio.h>
int main()
{
unsigned long long int i, a, b, rst;
scanf("%llu %llu", &a, &b);
rst = 1;
for (i = 0; i < b; i++){
rst = (rst * a) % 1000000007;
}
printf("%llu\n", rst);
return 0;
}

C - I'm having trouble coding a "rotate right" function

I'm having a little trouble writing my code to rotate my hexadecimal digits right. Below is a function I wrote, where, if you call on it, passing it like so: rotr(0x12345678, 4), it should return 0x81234567. Instead, it's only returning 7 digits (as opposed to eight, like in the original value = 0x12345678).
Can someone please help me understand what is going on in the bit level? I'm having trouble understanding why my current code is returning 0x123456f, instead of 0x81234567. Thanks in advance!
Edit: is it because I'm shifting 0x12345678 too early? I'm mainly trying to figure out why only seven digits return back, as opposed to eight.
unsigned int rotr(unsigned int x, int n) {
int i; //iterate for loop
unsigned int y; //masked last bit
unsigned int z; //final result
for (i=1; i<=n; i++) {
y = x & 0x1; //isolates last bit
x = x >> 1; //shift right 1
z = x | (y << (sizeof(x)-1)); //shifts mask back to first slot; OR
//it with x
}
return z;
}
sizeof(x) will give the size of the variable in bytes, while the shift operators work with numbers of bits. You need to convert these operands to use the same unit.
instead of sizeof(x) you should write 8*sizeof(x), it's looks generic because your input may be short int, long int or anything.
For Right Rotation instead of rotating loops you can try below logic.
#include<stdio.h>
unsigned int rotr(unsigned int x, int n) {
unsigned int z;
z = (x >> n) | (x << (8*sizeof(int) - n)) ;
return z;
}
int main()
{
unsigned int num= 0x12345678, n = 4, ret;
printf("before : %x\n",num);
ret= rotr(num,n);
printf("before : %x\n",ret);
}

Warning message when using pow() function in C programming language

I am writing a very basic program to print the range of an unsigned long long variable in C language (0 to ((2 ^ n) - 1) where n is the number of bits for the data type in any system (with C installed in it and according to the compiler). In my system, the size of a long long variable is 8 bytes.
I am using the following code:
#include<stdio.h>
#include<math.h>
int main()
{
unsigned long long n;
//n = pow(2, 63);
//n = (n * 2) - 1;
n = pow(2, 64) - 1;
printf("\nn: %llu\n", n);
return 0;
}
upon compiling, gcc gives me the following error:
Print_long_long_int.c:10:2: warning: overflow in implicit constant conversion [-Woverflow].
On executing it, I get the correct output of
n: 18446744073709551615
But, if I remove the single comments from the lines, and use them:
n = pow(2, 63);
n = (n * 2) - 1;
Instead of:
n = pow(2, 64) - 1;
It doesn't give me any such warning. And executes normally.
Why is this discrepancy happening?
Thanks!
When you are giving
pow(2,64) -1 ;
It exceeds the limit of unsigned long long. This is the reason you are getting that warning.
Range of unsigned long is 0 to 18,446,744,073,709,551,615
Result of pow(2,64) is 18446744073709551616.
Power should return an integer, and you're getting an unsigned long long. I just made a simple power function to handle unsigned long longs.
#include<stdio.h>
unsigned long long power(int base, int exponent)
{
unsigned long long n = 1;
int i;
for (i = 0; i < exponent ; i++)
n *= base;
return n;
}
int main()
{
unsigned long long n = power(2, 64) - 1;
printf("n: %llu\n", n);
return 0;
}

sizeof operator returns 4 for (char + short ) [duplicate]

This question already has answers here:
What happens here? sizeof(short_int_variable + char_variable)
(5 answers)
Closed 9 years ago.
Given this code snippet:
#include <stdio.h>
int main() {
short i = 20;
char c = 97;
printf("%d, %d, %d\n", sizeof(i), sizeof(c), sizeof(c + i));
return 0;
}
Why is sizeof(c + i) == 4?
c + i is an integer expression (integer promotion!), so sizeof() returns sizeof(int)
Integer types smaller than int are promoted when an operation is
performed on them. If all values of the original type can be
represented as an int, the value of the smaller type is converted to
an int; otherwise, it is converted to an unsigned int.
Integer promotions require the promotion of each variable (c and i) to int size.
short i = 20;
char c = 97;
//The two int values are added and the sum is truncated to fit into the char type.
char a = c + i;
printf("%d, %d, %d %d\n", sizeof(i), sizeof(c), sizeof(c + i),sizeof(a));
2, 1, 4 1
The C uses int for all integer calculation, if not specified otherwise. On your platform, int is clearly 32bit long, so sizeof returns 4. If your compiler would use 64bit integers, it would be 8.

weird output without typecasting

I was trying to execute this code through gcc compiler:
#include <stdio.h>
int main()
{
unsigned long long int x;
x = 75000 * 75000;
printf ("%llu\n", x);
return 0;
}
But it gave wrong output.
I then tried this:
#include <stdio.h>
int main()
{
unsigned long long int x;
x = (unsigned long long)75000 * (unsigned long long)75000;
printf ("%llu\n", x);
return 0;
}
And it gave correct output !
Why is this so?
The expression 75000 * 75000 is the multiplication of two integer constants. The result of this expression is also an integer and can overflow. The result is then assigned to an unsigned long long, but it has already overflowed so the result is wrong.
To write unsigned long long constants use the ULL suffix.
x = 75000ULL * 75000ULL;
Now the multiplication will not overflow.

Resources