Garbage value long long data type - c

I need to calculate a large number which has length about 9-10 digits. Msdn says that long long type has a range for:
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
But when i run this code i get a garbage value printed:
#include <stdio.h>
int main(){
int seed = 88888; //This will be always a 5 digit number so the square of
// it will be 9 or 10 digits length
long long square = seed * seed;
printf("square = %lld", square);
getchar();
return 0;
}
Output:
square = -688858048

seed is of type int. seed*seed will also be of type int. And 88888*88888 overflows the size of int. You then assign this garbage value to your long long.
Change the type of seed, or cast in you calculation:
long long square = ((long long) seed) * seed;

Related

range of long int, long long int and int

I have to print product of elements of array A mod 10^9+7,there should N elements in array and the constraints are 1<=N<=10^3 and 1<=A[i]<=10^3.
The code I wrote
#include<stdio.h>
int main()
{
int N, pro = 1;
scanf("%i", &N);
int arr[N];
for (int i = 0; i<N; i++) {
scanf("%i", &arr[i]);
pro = (pro*arr[i]) % (1000000007);
}
printf("%i", pro);
}
gave wrong answer but when I replaced int arr[N] to long int arr[N] and changed its precision specifier to %li it gave correct output.
My confusion is when the upper limit of array's elements is only 10^3 then why using long int worked and not just int.
i am using 64 bit windows OS and the inputs which i am giving are 3 digit numbers
as array elements for example 568,253 etc without any 0 in beginning.
Consider the case where N = 3 and A = [10^3,10^3,10^3].
After the second iteration, your product will be 10^9.
In the third iteration, your product will be (10^9 * 10^3) % 1000000007.
Before doing the modulo operation, the product would create integer overflow and hence the WA.
The problem may be the result of the expression (pro*arr[i]).
If we assume that the maximum value of pro is 1000000006 due to the modulo, and the maximum value of arr[i] is 10^3 as mentioned. So, this expression may take a value greater than a 32bit integer.
The other thing to look for is What the type of (pro * arr[i]) ? :
The compiler answers this question by look to the operands of the expression, and will set the return type, for integer, as the greater type of them.
If you set arr[] as an long int [] this expression will return a long integer, whereas, if you set arr[] as an int, it will return an int and so it'll be wrong :
int * int -> int
int * long int -> long int

How to print a very large value in c

I am newbie, please bear if my question is silly.
int main()
{
int x=60674;
printf("%lf \n",(double)(x*x));
printf("%lld \n",(long long)(x*x));
return 0;
}
Why is this not working?
x * x overflows, so you should cast them into long longs before the multiplication:
printf("%lld \n",((long long)x * (long long)x));
Additionaly you may use standardised ints:
#include <inttypes.h>
#include <stdio.h>
int main() {
int x=60674;
printf("%" PRIu64 "\n",(uint64_t)x * x);
return 0;
}
Moreover you do not need to cast both variables .. the * will impose using the bigger type of the two multipliers.
Btw you could just use unsigned int .. the result would fit in UINT_MAX which is 4294967295 (from here )
x is a signed integer that can hold value only upto -2,147,483,847 to +2,147,483,847 and on performing the operation
x * x
==> 60674 * 60674 = 3,681,334,276
which generally overflows the integer range. Hence you might need some big data type to hold that calculation 60674 * 60674
You can try two things to do that.
Change the data type of x from int to long or for more range long long
long long x = 60674;
Type cast the calculation to long range data type.
printf("%lld \n",((long long)x* (long long)x));

Why the factorial of 153 has failed in following program

I have created a myfun.h header file with two functions in it. A factorial function and amstrong function and a myfun.c file
Here is myfun.h program
void factorial(int n,int *fact)
{
int i;
*fact=1;
for(i=1;i<=n;i++)
*fact=*fact*i;
}
amstrong(int n)
{
int sum=0,num,rem,cube;
num=n;
while(num>0)
{
rem=num%10;
cube=rem*rem*rem;
num=num/10;
sum=sum+cube;
}
if(sum==n)
return(1);
else
return(0);
}
Here is the myfun.c program
#include<stdio.h>
#include "myfun.h"
int main()
{
int num,rev,f,code;
printf("Enter number :");
scanf("%d",&num);
code=amstrong(num);
if(code==1)
printf("\nNumber is amstrong\n");
else
printf("Number is not amstrong\n");
factorial(num,&f);
printf("Factorial of %d is %d ",num,f);
getch();
}
In this the amstrong function is working fine.But the factorial function is giving output 0. I haven't tried it without removing pointer variable. But if i want to run it with pointer variable then what changes i need to do?
The output of program is
Enter number: 153
Number is amstrong
Factorial of 153 is 0
153! = 2.01 E+269.
In case unsigned long long is 64 bits, it can hold a maximum value of 2^64 = 18.45 E+19.
You will need to use some form of "big int" library to calculate huge numbers like these.
This is happening because there is a every data type can hold upto a certain number. The reason that you are getting wrong answer is because the fact of 153 would be bigger then what an int variable can hold. It should work fine for smaller values.
Edit
To store larger numbers you can use long long int data type.
The minimum data type ranges you can use are:
short int and int: -32,767 to 32,767
unsigned short int and unsigned int: 0 to 65,535
long int: -2,147,483,647 to 2,147,483,647
unsigned long int: 0 to 4,294,967,295
int alone cannot store the value given by fact (153). Use smaller values for your case, otherwise change the type: use a long long int instead.
sizeof(long double) = 12bytes on a machine running 32-bit linux. The output can be printed by using %LE in printf. Output will be in exponential form.
EDIT
factorial(20) : 2432902008176640000 when using long long int
This is maximum you can get with long long int type of variable.
For greater ranges use long double.

Is there a maximum length of integers I can enter for C?

for the b/m, I am trying to sum up the digits of an integer. eg. if I enter 1234, i get the answer 1 + 2 + 3 + 4 = 10.
this works for integers up to 10 digits long. after that, if i enter an integer with 11 digits like 12345678912, it returns me a negative answer.
Could anyone help to explain why this is so please? And if there's anyway I can get around it?
Thank you!
#include <stdio.h>
int main(void)
{
int number, single_digit, sum;
printf("What number would you like to sum:\n");
scanf("%i", &number);
sum = 0;
while(number != 0)
{
single_digit = number % 10;
sum += single_digit;
number = number / 10;
}
printf("The sum of the number is %i.\n", sum);
return 0;
}
Yes, the maximum value an integer can hold is INT_MAX (whose value depends on your platform).
An unsigned int can hold larger (positive) numbers, up to UINT_MAX.
You may be able to fit more in unsigned long or unsigned long long - again, the details are platform-specific. After that, you're looking for a bignum library.
NB. since you just want to sum the digits, using something like haccks' approach is much simpler, and less likely to overflow. It's still possible, though.
The maximum limit for an int is INT_MAX. You are getting -ve value because 12345678912 doesn't fit in the range of int and causes integer overflow.
Better to change your main's body to
sum = 0;
int ch;
printf("Enter the number would you like to sum:\n");
while((ch = getchar()) != '\n' && ch != EOF)
{
sum += ch - '0';
}
printf("The sum of the number is %i.\n", sum);
Since getchar reads single character at a time, you will get your desired output by adding these to sum.
This is happening because an int is only 4 bytes. What that means is any number larger than 2^31 will cause the buffer to overflow. A more detailed explanation can be found here: http://en.wikipedia.org/wiki/Integer_overflow. If you want to get around it, use an unsigned int instead, it will let you go up to 2^32 instead, but it will not let you have any negative numbers.
The int type is (usually) a signed 32-bit integer (you can see your size by printing sizeof(int)*8 to get the number of bits.
This means that the maximum value you can store in an int is 2^32 - 1, but, because int is signed, the range is actually half that.
In C a specific type of integer is stored in a fixed amount of memory. On all current architectures an int is stored in 32 bits. Since int carries a sign, the most significant bit is assigned to the sign. This means that the biggest integer you can store in an int is 2^31 - 1. You are seeing a negative number because the your int is overflowing into the sign bit and making it negative.
Number types in c are limited. You can find the max ints in limits.h
You should read the input as a string (char array) and process each character to allow arbitrary* lenght numbers.
*The sum still need to be less than max int. the input string must be big enough to contain what the user writes
An integer with 11 digits like 12345678912 if too large to fit in number which is an int on your platform.
In C, an int has of range of at least -32767 to 32767. On your platform it apparently has the range -2147483648 to +2147483647.
If code is to read the entire integer at once, the maximum number of digits is limited by the range of the various available integer types.
C provides an integer type called intmax_t and its unsigned partner uintmax_t which typically has the maximum range available on a given platform.
#include <inttypes.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void MaximalSumOFDigits(void) {
uintmax_t number;
double widthf = log10(UINTMAX_MAX);
int widthi = ((int) floor(widthf)) - 1;
char buf[widthi + 2];
printf("What number would you like to sum: (up to %d digits)\n", widthi);
fgets(buf, sizeof buf, stdin);
char *endptr;
errno = 0;
number = strtoumax(buf, &endptr, 10);
if (*endptr != '\n')
Handle_UnexpectedInput();
if (errno) // This should not easily happen as buffer has limited length
Handle_TooBigANumber();
int sum = 0;
while (number > 0) { // avoiding ASCII dependence
sum += number % 10;
number /= 10;
}
printf("The sum of the number is %d.\n", sum);
}
With a 64-bit uintmax_t, allows numbers up to
18446744073709551615 (any 19 digit number and some 20 digit numbers)
The above suggests to the user input limit of limit of
_9999999999999999999 (any 19 digit number)

Explaination of an output

Hi I have implemented a C code in visual C++ and and did some modification in it for debugging. Here is the code
long long unsigned factorial(long long unsigned int * n) {
if (*n<=1) return 1;
else {
(*n)--;//This statement here .......
printf("calculating %d * factorial %d \n",*n,*n); -- used for debugging
return ((*n+1) * factorial(n));
}
}
The final output(value of factorial) is coming as expected but it is output of debug statement that surprises me.
calculating 4 * factorial 0
calculating 3 * factorial 0
calculating 2 * factorial 0
calculating 1 * factorial 0
120
Same value *n is used twice in every debug statement and it is showing different values. How is this possible that same value when used twice in a statement, gives different results.
I'm only guessing here, but the format code "%d" is for int, while you pass a long long. That's a difference of 32 bits per value. Use "%llu" instead ("ll" for long long, the "u" for unsigned).
Because you are using a wrong format for unsigned long long, test this one:
#include <stdio.h>
long long unsigned factorial(long long unsigned int * n) {
if (*n<=1) return 1;
else {
(*n)--;//This statement here .......
printf("calculating %llu * factorial %llu \n",*n,*n);
return ((*n+1) * factorial(n));
}
}
int main(void)
{
long long unsigned int n = 4ULL;
n = factorial(&n);
printf("%llu\n", n);
return 0;
}
You are modifying the value of n at each recursion iteration.
When you are using recursion with a pointer:
return ((*n+1) * factorial(n));
You first calculating the value of factorial(n). When the last recursion iteration is reached, you already decremented the n till 0.
So, please do not pass n by reference .

Resources