Displaying very large number - c

As we know that 4294967295 is the largest number in unsigned int if I multiply this number by itself then how to display it? I have tried:
long unsigned int NUMBER = 4294967295 * 4294967295;
but still getting 1 as answer.

You are getting an overflow. Consider the muplication in hexadecimal:
0xffffffff * 0xffffffff == 0xfffffffe00000001
^^^^^^^^
only the last 32 bits are returned
The solution is to use a larger type such as long long unsigned:
long long unsigned int NUMBER = 4294967295ULL * 4294967295ULL;
The suffix ULL means unsigned long long.
See it working online: ideone

The multiplication overflows.
#include <stdio.h>
int main()
{
unsigned int a = 4294967295;
unsigned int b = 4294967295;
// force to perform multiplication based on larger type than unsigned int
unsigned long long NUMBER = (unsigned long long)a * b;
printf("%llu\n", NUMBER);
}

You state in your question that you know max int is equal to 4294967295. That means that you can't store a number larger than that if you are using unsigned int.
C longs store up to 18,446,744,073,709,551,615 when unsigned on a 64 bit unix system [source] so you need only suffix your numbers with UL : 4294967295UL
If you aren't using a 64-bit unix system then you should use long long unsigned int and suffix with LL

Yes, it's an overflow. If you are using c, there isn't any easy way to do such big number multiply as i knew. Maybe you need write one by yourself. In fact some language support such features originally.

Related

Multiplying very large hex numbers and printing them in C

I want to multiply 2 very big hex numbers and print them out like for example:
28B2D48D74212E4F x 6734B42C025D5CF7 = 1068547cd3052bbe5688de35695b1239
Since I expected it to be a very big number I used unsigned long long int type:
unsigned long long int x = 0x28B2D48D74212E4F;
unsigned long long int y = 0x6734B42C025D5CF7;
and print the multiplication like this:
fprintf(stdout, "%llx\n", x*y);
What I get is exactly the half of the expected result:
5688de35695b1239
Why does it truncate it to exactly the half? Is there something bigger than unsigned long long?
The response you're looking for won't fit in a 64-bit unsigned long long, which is the normal size on a 64-bit platform; any excess during multiply is overflow and dropped.
Newer versions of GCC do support 128-bit integers on 64-bit machines with __int128 (and unsigned __int128), and this works:
unsigned long long int x = 0x28B2D48D74212E4FULL;
unsigned long long int y = 0x6734B42C025D5CF7ULL;
unsigned __int128 xy = x * (unsigned __int128)y;
Note that you have to cast one of x or y to the wider type so the multiplication is done in 128 bits; otherwise that promotion to 128 is not done until after the (truncated) 64-bit multiply.
The problem is, as far as I can tell, printf() doesn't have a way to do this easily, so you're going to have to roll your own a bit.
Some reasonable discussion here: how to print __uint128_t number using gcc?
But this worked for me on:
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)
#include <stdio.h>
int main()
{
unsigned long long int x = 0x28B2D48D74212E4F;
unsigned long long int y = 0x6734B42C025D5CF7;
unsigned __int128 xy = x * (unsigned __int128)y;
printf("Result = %016llx%016llx\n",
(unsigned long long)( xy >> 64),
(unsigned long long)( xy & 0xFFFFFFFFFFFFFFFFULL));
return 0;
The casts inside the printf are important: otherwise the shifting/masking are done in 128-bit scalars, and those 128 bits pushed onto the stack, but then each %llx expects 64 bits.
Note that this is all entirely dependent on the underlying platform and is not portable; there's surely a way to use various #ifdefs and sizeofs to make it more general, but there's probably no super awesome way to make this work everywhere.

I am trying to store value in long long int type but giving wrong return

I am trying to store "10000000000000000000"(19 zeros) inside long long int data type.
#if __WORDSIZE == 64
typedef long long int intmaximum_t;
#else
__extension__
typedef unsigned long int intmaximum_t;
#endif
const intmaximum_t = 10000000000000000000;
But it is giving output "-8446744073709551616" (in negative).
I have 64 bit machine with ubuntu OS. How to store this value?
The largest possible value for a 64 bit long long int is 9,223,372,036,854,775,807. Your number is bigger than that. (Note that this number less the one you get is one off the number you actually want - that's not a coincidence but a property of 2's complement arithmetic).
It would fit in an unsigned long long int, but if you need an unsigned type you'll need to use a large number library for your number, or int128_t if your compiler supports it.
The value 10000000000000000000 is too large to fit in a signed 64-bit integer but will fit in an unsigned 64-bit integer. So when you attempt to assign the value it gets converted in an implementation defined way (typically by just assigning the binary representation directly), and it prints as negative because you are most likely using %d or %ld as your format specifier.
You need to declare your variable as unsigned long long and print it with the %llu format specifier.
unsigned long long x = 10000000000000000000;
printf("x=%llun", x);

Wrong answer in C for long number calculations

long int k=(long int)(2000*2000*2000);
the above calculation is giving me wrong answer in C. What is wrong?
If a C integer constant fits in an int, it is of type int. So your expression is evaluated as:
long int k = (long int)((int)2000*(int)2000*(int)2000);
If int isn't large enough to hold the result of the multiplication, you'll get a signed integer overflow and undefined behavior. So if long is large enough to hold the result, you should write:
long k = 2000L * 2000L * 2000L;
The L suffix forces the type of the literal to long (long is equivalent to long int).
But on most platforms, even long is only a 32-bit type, so you have to use long long which is guaranteed to have at least 64 bits:
long long k = 2000LL * 2000LL * 2000LL;
The LL suffix forces the type of the literal to long long.
2000 is of type int, so 2000*2000*2000 is also of type int.
Assuming a 32-bit int (which is actually more than the standard requires, since an int is not required by the standard to represent a value more than 32767) the maximum representable value is about 2,147,483,647 (commas inserted for readability) which is less than 8,000,000,000.
You will probably want to do the calcuation as 2000LL*2000*2000 which takes advantage of multiplication being left-right associative, and will promote all the 2000 values to long long int before doing the multiplication. Your variable will also need to be of type long long int if you want a guarantee of being able to store the result.
Holt's answer is the correct one, I am just leaving this here as caveat!
You could try to use:
long long int
instead of
long int
However, in my local machine, it has no effect:
#include <stdio.h>
int main(void)
{
long int k=(long int)(2000*2000*2000);
printf("With long int, I am getting: %ld\n", k);
long long int n = 2000*2000*2000;
printf("With long long int, I am getting: %lld\n", n);
return 0;
}
Output:
With long int, I am getting: -589934592
With long long int, I am getting: -589934592
Warnings:
../main.c:6:36: warning: integer overflow in expression [-Woverflow]
long int k=(long int)(2000*2000*2000);
^
../main.c:9:32: warning: integer overflow in expression [-Woverflow]
long long int n = 2000*2000*2000;
Even this:
unsigned long long int n = 2000*2000*2000;
printf("With long long int, I am getting: %llu\n", n);
will overflow too.
There are two problems in your code:
long int is (on most architecture) not enough to store 8e9.
When you do 2000 * 2000 * 2000, operations are made using "simple" int, thus, int * int * int = int so you cast the result to an int and then to a long int.
You need to use long long int and specify that you want long long int:
long long int k = 2000LL*2000LL*2000LL;
Notice the extra LL after 2000 saying "It's 2000, but as a long long int!".
You can't just multiply the values together as ordinary precision integers and then cast the result to a higher precision, because the result has already overflowed at that point. Instead, the operands need to be higher precision integers before they're multiplied. Try the following:
#include <stdio.h>
int main(void)
{
long long int n = (long long int)2000*(long long int)2000*(long long int)2000;
printf("long long int operands: %lld\n", n);
return 0;
}
On my machine, this gives:
long long int operands: 8000000000

Unsigned long long with negative value

while exploring linux code, came across many definition like below. If ULL is unsigned long long, why it has negative value -11? What the value of below macro?
#define BTRFS_FREE_SPACE_OBJECTID -11ULL
-11ULL is the same as - (11ULL). 11ULL is an unsigned long long with value 11. If you read up how arithmetic operations on unsigned types work, if the mathematical result does not fit into the range, then the largest value + 1 is added or subtracted repeatedly.
The mathematical result -11 doesn't fit, so the largest unsigned long long + 1 is added, and -11ULL gives ten less than the largest possible unsigned long long value. A huge positive number, not negative.
unsigned int a=-1;
is the same as:
unsigned int a=0xffffffff;

Why there is a need of cast in the following program?

Posted the whole code(if needed)
/* multiplication of n1 and n2*/
#include<stdio.h>
int arr[200]; //for storing the binary representation of n2
int k=0; // to keep the count of the no of digits in the binary representation
void bin(int n)
{
if(n>1)
bin(n/2);
arr[k++]=n%2;
}
int main()
{
int n1=1500000;
int n2=10000000;
int i=0,t=0;
long long int temp,pro=0;
bin(n2); // calculating the binary of n2 and stroring in 'arr'
for(i=k-1; i>=0 ;i--)
{
temp = (n1*arr[i]) << t; /* Why need cast here ? */
pro = pro + temp;
t++;
}
printf("product: %lld",pro);
return 0;
}
In the above program, I am not getting the desired output. But when I do this:
temp = (n1*(long long int)arr[i]) << t;,
then I am getting the correct output !
I am not able to understand the above behavior ?
It seems likely that on your system int is 32 bits and long long int is 64 bits.
n1 and arr[i] are both int, and result of multiplication is then int. But there is not enough bits in int to hold the answer because it is too big.
When you cast one member of the operation to long long int, then result will also be long long int too.
n1, as well as arr[i], are integers. Without the cast, you get an integer multiplication (which may overflow), shift that integer left (again producing an integer result that may overflow), then assign that integer to temp.
If you cast arr[i] to long long, all calculations are done in long. So, if your integers are 32 bit (and thus limited to about 2e10), your integers will overflow, but the long longs, which should be 64 bit, will not.
I suspect that an int isn't large enough to store the result of (n1*arr[i]), so casting to a (long long int) gives enough room to store the result.
int Not smaller than short. At least 16 bits.
long long int Not smaller than long. At least 64 bits.
Have a look at C++ Data Types.
a multiplication between two integer goes into an integer unless you cast one of them to something else. So in the first multiplication the result is stored into an integer (32 bit signed on a 32 bit system), in the second case into a long long (64 bit unsigned on a 32 bit system). You may prefer using types like int64_t to have better portability.
You can use sizeof(int), sizeof(long long) to see the difference between the two.

Resources