Nehal Samee
Nehal Samee

Reputation: 166

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

Upvotes: 0

Views: 866

Answers (3)

Bob__
Bob__

Reputation: 12759

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);
    }
}

Upvotes: 0

4386427
4386427

Reputation: 44284

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;
  }

Upvotes: 3

klutt
klutt

Reputation: 31389

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 */
}

Upvotes: 1

Related Questions