range of long int, long long int and int - c

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

Related

No output for long long int variables

Here is a code snippet:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
The above code does not work for any input. That is, it seems like it has crashed,though I could not understand where I'm mistaken. I guess the part with %lld in the printf has problems. But Ido not know how to fix it. I'm using code blocks.
Some expected outputs for corresponding inputs are as follows:
Input: 6 6 4
Output: 4
Input: 1000000000 1000000000 1
Output: 1000000000000000000(10^18).
APPEND:
So, I'm giving the link of the main problem below. The logic of my code seemed correct to me.
https://codeforces.com/contest/1/problem/A
As it's been pointed out in comments/answers the problem is that m and n is unsigned so your loops can only stop if m and n are a multiple of a.
If you look at the input 6 6 4 (i.e. m=6 and a=4), you can see that m first will change like m = 6 - 4 which leads to m being 2. So in the next loop m will change like m = 2 - 4 which should be -2 but since m is unsigned it will wrap to a very high positive number (i.e. UINT_MAX-1) and the loop will continue. That's not what you want.
To fix it I'll suggest you drop the while loops and simply do:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
One problem with this solution is that the sum (m + a - 1) may overflow (i.e. be greater than UINT_MAX) and therefore give wrong results. You can fix that by adding an overflow check before doing the sum.
Another way to protect against overflow could be:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
This code can then be reduced to:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}
while(m>0){
m-=a;
p++;
}
will run until m is equal to 0, since it cannot be negative because it is unsigned. So if m is 4 and a is 6, then m will underflow and get the maximum value that m can hold minus 2. You should change the input variables to signed.
4386427 shows how you can use math to remove the loops completely, but for the more general case, you can do like this:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
Of course, you need to do the same thing for the second loop.
Another thing, check return value of scanf:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
Using an unsigned type isn't always the best choice to represent positive values, expecially when its modular behavior is not needed (and maybe forgotten, which leads to "unexpected" bugs). OP's use case requires an integral type capable of store a value of maximum 109, which is inside the range of a 32-bit signed integer (a long int to be sure).
As 4386427's answer shows, the while loops in OP's code may (and should) be avoided anyways, unless a "brute force" solution is somehow required (which is unlikely the case, given the origin of the question).
I'd use a function, though:
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}

Adding Big Ints from Array in C Results in No Output

I am new to C (and programming in general, minus a few weeks with Python). I am interested in learning how information is handled on a machine level, therefore I moved to C. Currently, I am working through some simple coding challenges and am having trouble finding information to resolve my current issue.
The challenge is to take N large integers into an array from input and print the sum of the numbers. The transition from Python to C has actually been more difficult than I expected due to the simplified nature of Python code.
Example input for the code below:
5
1000000001 1000000002 1000000003 1000000004 1000000005
Expected output:
5000000015
Code:
int main() {
long long unsigned int sum = 0;
int nums[200], n, i;
scanf("%i", &n);
for (i = 0; i =! n; i++) {
scanf("%i", &nums[i]);
sum = sum + nums[i];
}
printf("%llu", sum);
return 0;
}
The program seems to accept input for N, but it stops there.
One last question, in simple terms, what is the difference between a signed and unsigned variable?
Change your for loop like this
for (i = 0; i != n; i++) {
scanf("%i", &nums[i]);
sum = sum + nums[i];
}
if you say i =! n that is the same as i = !n. What that does is to assign the negated value of n to i. Since you gave a non-zero value to n the result is zero and the loop terminates.
Welcome to C!
Regarding the signed vs unsigned question. signed types can have negative values and unsigned can't. But they both take up the same space (number of bits) in memory. For instance, assuming twos' complement representation and a 32 bit integer, the range of values is
singed : -2^31 to 2^31 - 1 or –2147483648 to 2147483647
unsigned : 0 to 2^32 - 1 or 0 to 4294967295

How to take modulus of a large value stored in array?

Suppose I have a integer array containing digits and I want to take modulus of value stored in it, i.e
int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9}
and convert it into a number like 987654321987654321987654321987654321.
In C language long long int permits only 10^18. I want to take modulus with 10^9+7. How can i do that?
Program:
int main()
{
int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9};
long long int temp=0;
int i;
for(i=0;i<36;i++)
{
temp=temp+a[i]*pow(10,i);
}
temp=temp%1000000007;
printf("%lld",temp);
return 0;
}
Since 36 decimal digits is too much for a typical long long, you need to perform your modulus operation during the conversion:
int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9};
long long int temp=0;
for(int i=35 ; i >= 0 ; i--) {
temp = 10*temp + a[i];
temp %= 1000000007;
}
printf("%lld",temp);
I made two changes to your code:
Fixed the way you convert an array of digits to a number - your code used pow, and treated digits at higher indexes as higher-order digits. This creates precision problems once you get past the highest power of ten that can be represented as double.
Moved the %= into the loop - your code does not let the number overflow by keeping the value in the range from 0 to 1000000006, inclusive.
Running this code produces the same value that you would obtain with a library that supports arbitrary precision of integers (I used Java BigInteger here).

C code running well only upto a certain point

I wrote this simple code to generate 4th power of all positive integers up to 1005. It works fine only up to integer 215. After that it gives erroneous readings. why so?
# include<stdio.h>
int main(void)
{
int i;
unsigned long long int j;
for (i = 1; i <= 1005; i++){
j = i*i*i*i;
printf("%i.........%llu\n",i,j);
}
return 0;
}
You can fix it by making this small change.
unsigned long long i;
The problem is that in the line j = i*i*i*i;, the right hand side is being calculated as an int before it is being assigned to j. Because of this if i^4 exceeds integer limits, it will basically start to go first negative and start cycling around when higher bits get clipped. When the negative number is assigned to j, since j is unsigned, -i becomes max - i, which is where the huge numbers come from. You will also need to change the printf format specifier from %i to %llu for i.
You can also fix this by doing the below
j = (unsigned long long)i*i*i*i;
This basically forces a cast up to the type of j before performing the multiplication.
Sanity check - 215 ^4 = 2136750625 which is very close to the upper limit of signed int of 2,147,483,647.
i*i produces an int. And so do i*i*i and i*i*i*i. 215 is the greatest positive integer whose 4th power fits into a 32-bit int.
Beyond that the result is typically truncated (typically because strictly speaking you are having a case of undefined behavior; signed integer overflows result in UB per the C standard).
You may want to cast i to unsigned long long or define it as unsigned long long, so the multiplications are 64-bit:
j = (unsigned long long)i*i*i*i;

Why does this division result in zero?

I was writing this code in C when I encountered the following problem.
#include <stdio.h>
int main()
{
int i=2;
int j=3;
int k,l;
float a,b;
k=i/j*j;
l=j/i*i;
a=i/j*j;
b=j/i*i;
printf("%d %d %f %f\n",k,l,a,b);
return 0;
}
Can anyone tell me why the code is returning zero for the first and third variables (k and a)?
Are you asking why k and a show up as zero? This is because in integer division 2/3 = 0 (the fractional part is truncated).
What I think you are experiencing is integer arithmetic. You correctly suppose l and b to be 2, but incorrectly assume that k and a will be 3 because it's the same operation. But it's not, it's integer arithmetic (rather than floating-point arithmetic). So when you do i / j (please consider using some whitespace), 2 / 3 = 0.33333... which is cast to an int and thus becomes 0. Then we multiply by 3 again, and 0 * 3 = 0.
If you change i and j to be floats (or pepper your math with (float) casts), this will do what you expect.
You haven't said what you're getting or what you expect, but in this case it's probably easy to guess. When you do 'a=i/j*j', you're expecting the result to be roughly .2222 (i.e. 2/9), but instead you're getting 0.0. This is because i and j are both int's, so the multiplication and (crucially) division are done in integer math, yielding 0. You assign the result to a float, so that 0 is then converted to 0.0f.
To fix it, convert at least one operand to floating point BEFORE the division: a = (float)i/j*j);
this is due to how the c compiler treats int in divisions:
#include <stdio.h>
int main()
{
int i=2;
int j=3;
int k,l;
float a,b;
k=i/j*j; // k = (2/3)*3=0*3=0
l=j/i*i; // l = (3/2)*2=1*2=2
a=i/j*j; // same as k
b=j/i*i; // same as b
printf("%d %d %f %f/n",k,l,a,b);
return 0;
}
If you're asking why k and a are 0: i/j*j is the same as (i/j)*j. Since j is larger than i, i/j is 0 (integer division). 0*j is still 0, so the result (k) is 0. The same applies to the value of a.
it doesn’t matter if you’re variable is float or not, as long you’re using
integer / integer , you’ll get 0,
but because you’re using a float output, you get 0.0

Resources