10

Possible Duplicate:
How do you printf an unsigned long long int?

#include <cstdio>

int main ()
{
    unsigned long long int n;
    scanf("%llu",&n);
    printf("n: %llu\n",n);
    n /= 3;
    printf("n/3: %llu\n",n);
    return 0;
}

Whatever I put in input, I get very strange output, for example:

n: 1
n/3: 2863311531

or

n: 2
n/3: 2863311531

or

n: 1000
n/3: 2863311864

What's the reason? How should I do this correctly?

(g++ 3.4.2, Win XP)

Community
  • 1
  • 1
drevv
  • 155
  • 2
  • 2
  • 5
  • 2
    Can you please write, what is the value of sizeof(unsigned long long int) ? And try 'unsigned long int' instead of '..long long..' – Zaur Nasibov May 13 '11 at 20:17
  • Also works for me on GCC 4.2.1 – Adam May 13 '11 at 20:23
  • sizeof(unsigned long long int) returns 8. I've changed variable type to unsigned long int and it worked fine, but sizeof(unsigned long int) returns 4, so it's regular int. I need wider range. – drevv May 13 '11 at 20:24
  • `#include ` implies C++, but `unsigned long long int` and `%llu` imply C. Which do you want to use? – CB Bailey May 13 '11 at 20:25
  • And I've checked the same code on Linux and it works fine... – drevv May 13 '11 at 20:25
  • Thank you Charles! I've replaced with and everything's ok :) – drevv May 13 '11 at 20:27
  • `#include ` with `using namespace std;` also works. Thank you for your answers! – drevv May 13 '11 at 20:32
  • Strange, the error sounds like you were calling a `printf` without a prototype in scope. While this would explain the behaviour if you were compiling as C (it would be undefined behavior), the fact that `using namespace std` "worked" suggests that you were compiling as C++ which means that calling `printf` without a prototype should have caused a compile error. – CB Bailey May 13 '11 at 20:40

1 Answers1

12

The problem is that MinGW relies on the msvcrt.dll runtime. Even though the GCC compiler supports C99-isms like long long the runtime which is processing the format string doesn't understand the "%llu" format specifier.

You'll need to use Microsoft's format specifier for 64-bit ints. I think that "%I64u" will do the trick.

If you #include <inttypes.h> you can use the macros it provides to be a little more portable:

int main ()
{
    unsigned long long int n;
    scanf("%"SCNu64, &n);
    printf("n: %"PRIu64"\n",n);
    n /= 3;
    printf("n/3: %"PRIu64"\n",n);
    return 0;
}

Note that MSVC doesn't have inttypes.h until VS 2010, so if you want to be portable to those compilers you'll need to dig up your own copy of inttypes.h or take the one from VS 2010 (which I think will work with earlier MSVC compilers, but I'm not entirely sure). Then again, to be portable to those compilers, you'd need to do something similar for the unsigned long long declaration, which would entail digging up stdint.h and using uint64_t instead of unsigned long long.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760