mersenneforum.org Using long long's in Mingw with 32-bit Windows XP
 User Name Remember Me? Password
 Register FAQ Search Today's Posts Mark Forums Read

 2009-09-30, 23:57 #1 grandpascorpion     Jan 2005 Transdniestr 503 Posts Using long long's in Mingw with 32-bit Windows XP Hi, I'm using Mingw version 5.1.6 within Windows XP (32-bit). I'd like to use 64-bit integers within C code but I'm running into problems. unsigned long z = 2*3*4*5*6*7*8*9*10*11*12; long long unsigned int zz = z*13*14; printf("Here is zz: %I64u\n"; After checking on-line, I found that the correct format to use is (the Microsoft-specific) %I64u, but this prints the lower 32 bits only. (Note: making z a "long long unsigned int" doesn't change the output) ============================================== I found a different problem doing simple arithmetic: unsigned long z = 2*3*4*5*6*7*8*9*10*11*12; long long unsigned int zz = z*13*14; long long unsigned int b = 175*z; long long unsigned int c = zz-b; // 7 * factorial(12) printf("c is %I64u\n",c); The correct answer is only: 3353011200 (< 2^32) but this code prints out an incorrect number (18446744072767595220) that is more greater than 2^32. ////////////////////////////////////////////////////////// Any insight would be appreciated. Thanks. (The background is that I have some gmplib code that I wrote which I want to speed up, if possible. I think I could do so by replacing some of the "big ints" with long longs.)
 2009-10-01, 00:12 #2 R. Gerbicz     "Robert Gerbicz" Oct 2005 Hungary 22·367 Posts "long long unsigned int" is in wrong order. I think you want: "unsigned long long int". And if %I64u doesn't works then try the other format: %llu. One of them should be good.
 2009-10-01, 00:28 #3 grandpascorpion     Jan 2005 Transdniestr 1F716 Posts Mea culpa Sorry, I see my error. I was doing calculations with an "unsigned long int" and wasn't doing an apparently necessary cast to "unsigned long long int". Both using the long long type and explicitly casting the long to it worked. %I64u is definitely the format to use in this scenario. And it turns out, the position of "unsigned" doesn't matter. Thanks for your feedback though. ===================================== Unfortunately, it looks like there isn't built-in functions to initialize/set an mpz_t to a long long. mpz_init_set_ui(a,b) just sets a to the lower 32-bits of b. Last fiddled with by grandpascorpion on 2009-10-01 at 00:41
2009-10-01, 00:36   #4
rogue

"Mark"
Apr 2003
Between here and the

2×7×11×41 Posts

Quote:
 Originally Posted by R. Gerbicz "long long unsigned int" is in wrong order. I think you want: "unsigned long long int". And if %I64u doesn't works then try the other format: %llu. One of them should be good.
"long long int" is redundant. "long long" is sufficient. For portable code, %llu should be used.

Also if you are using MinGW, there is probably a header called stdint.h. This has a predefined uint64_t variable type.

Finally, I try to avoid using "int" because some compilers treat an int as a 16 bit value (aka short int), even though the CPU and OS are 32-bit. You could use long, which will be 32 bits or 64 bits (depending upon the compiler, OS, and compiler options). I don't know if any compiler defines a long as 16 bits. I always use stdint.h to guarantee portability. Unfortunately M$doesn't have such a header in Visual Studio, but you can #typedef those datatypes using WORD and DWORD appropriately to ensure portability. Last fiddled with by rogue on 2009-10-01 at 00:50 2009-10-01, 01:03 #5 grandpascorpion Jan 2005 Transdniestr 503 Posts Quote:  Originally Posted by rogue "long long int" is redundant. "long long" is sufficient. For portable code, %llu should be used. Also if you are using MinGW, there is probably a header called stdint.h. This has a predefined uint64_t variable type. Finally, I try to avoid using "int" because some compilers treat an int as a 16 bit value (aka short int), even though the CPU and OS are 32-bit. You could use long, which will be 32 bits or 64 bits (depending upon the compiler, OS, and compiler options). I don't know if any compiler defines a long as 16 bits. I always use stdint.h to guarantee portability. Unfortunately M$ doesn't have such a header in Visual Studio, but you can #typedef those datatypes using WORD and DWORD appropriately to ensure portability.
Unfortunately, %llu doesn't work for Mingw but thanks for the stdint tip.
It's unlikely I would port it but if so I could I always have conditional compilation based on that format string.

 2009-10-01, 01:26 #6 jasonp Tribal Bullet     Oct 2004 2·29·61 Posts If you include inttypes.h, you get macros to insert into format strings that will print 64-bit values correctly. On my mingw installation they are Code: inttypes.h:#define PRId64 "I64d" inttypes.h:#define PRIi64 "I64i" inttypes.h:#define PRIo64 "I64o" inttypes.h:#define PRIu64 "I64u" inttypes.h:#define PRIx64 "I64x" inttypes.h:#define PRIX64 "I64X" Admittedly it makes the format string painful to write, i.e. printf("I have computed %" PRId64 "\n", answer); Last fiddled with by jasonp on 2009-10-01 at 01:28
2009-10-01, 02:14   #7
grandpascorpion

Jan 2005
Transdniestr

503 Posts

Quote:
 Originally Posted by jasonp If you include inttypes.h, you get macros to insert into format strings that will print 64-bit values correctly. On my mingw installation they are Code: inttypes.h:#define PRId64 "I64d" inttypes.h:#define PRIi64 "I64i" inttypes.h:#define PRIo64 "I64o" inttypes.h:#define PRIu64 "I64u" inttypes.h:#define PRIx64 "I64x" inttypes.h:#define PRIX64 "I64X" Admittedly it makes the format string painful to write, i.e. printf("I have computed %" PRId64 "\n", answer);
Ugly but portable :) . Thanks.

2009-10-04, 12:13   #8
ldesnogu

Jan 2008
France

547 Posts

Quote:
 Originally Posted by jasonp If you include inttypes.h, you get macros to insert into format strings that will print 64-bit values correctly. On my mingw installation they are Code: inttypes.h:#define PRId64 "I64d" inttypes.h:#define PRIi64 "I64i" inttypes.h:#define PRIo64 "I64o" inttypes.h:#define PRIu64 "I64u" inttypes.h:#define PRIx64 "I64x" inttypes.h:#define PRIX64 "I64X" Admittedly it makes the format string painful to write, i.e. printf("I have computed %" PRId64 "\n", answer);
It's ugly but it has another advantage on top of working on 32-bit Windows and Linux: it will do the correct thing when you go to a 64-bit platform where a 64-bit integer is defined as a long instead of a long long (%lu vs %llu).

 Similar Threads Thread Thread Starter Forum Replies Last Post ThomRuley Msieve 3 2013-11-30 04:52 davar55 Lounge 60 2013-07-30 20:26 lycorn Lounge 24 2013-01-15 01:53 panic Hardware 9 2009-09-11 05:11 schickel Lounge 2 2009-02-22 12:31

All times are UTC. The time now is 18:22.

Tue May 18 18:22:19 UTC 2021 up 40 days, 13:03, 0 users, load averages: 1.94, 1.98, 1.99