mersenneforum.org  

Go Back   mersenneforum.org > Extra Stuff > Programming

Reply
 
Thread Tools
Old 2009-09-30, 23:57   #1
grandpascorpion
 
grandpascorpion's Avatar
 
Jan 2005
Transdniestr

1111101112 Posts
Default 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.)
grandpascorpion is offline   Reply With Quote
Old 2009-10-01, 00:12   #2
R. Gerbicz
 
R. Gerbicz's Avatar
 
"Robert Gerbicz"
Oct 2005
Hungary

23×3×59 Posts
Default

"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.
R. Gerbicz is offline   Reply With Quote
Old 2009-10-01, 00:28   #3
grandpascorpion
 
grandpascorpion's Avatar
 
Jan 2005
Transdniestr

503 Posts
Default 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
grandpascorpion is offline   Reply With Quote
Old 2009-10-01, 00:36   #4
rogue
 
rogue's Avatar
 
"Mark"
Apr 2003
Between here and the

2×3,001 Posts
Default

Quote:
Originally Posted by R. Gerbicz View Post
"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
rogue is offline   Reply With Quote
Old 2009-10-01, 01:03   #5
grandpascorpion
 
grandpascorpion's Avatar
 
Jan 2005
Transdniestr

503 Posts
Default

Quote:
Originally Posted by rogue View Post
"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.
grandpascorpion is offline   Reply With Quote
Old 2009-10-01, 01:26   #6
jasonp
Tribal Bullet
 
jasonp's Avatar
 
Oct 2004

348910 Posts
Default

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
jasonp is offline   Reply With Quote
Old 2009-10-01, 02:14   #7
grandpascorpion
 
grandpascorpion's Avatar
 
Jan 2005
Transdniestr

503 Posts
Default

Quote:
Originally Posted by jasonp View Post
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.
grandpascorpion is offline   Reply With Quote
Old 2009-10-04, 12:13   #8
ldesnogu
 
ldesnogu's Avatar
 
Jan 2008
France

23×67 Posts
Default

Quote:
Originally Posted by jasonp View Post
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).
ldesnogu is offline   Reply With Quote
Reply

Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
How long is too long? ThomRuley Msieve 3 2013-11-30 04:52
very long int davar55 Lounge 60 2013-07-30 20:26
How long will the project take? lycorn Lounge 24 2013-01-15 01:53
I think it's gonna be a long, long time panic Hardware 9 2009-09-11 05:11
How long is too long? schickel Lounge 2 2009-02-22 12:31

All times are UTC. The time now is 16:35.

Wed Nov 25 16:35:59 UTC 2020 up 76 days, 13:46, 3 users, load averages: 1.58, 1.84, 1.79

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.

This forum has received and complied with 0 (zero) government requests for information.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
A copy of the license is included in the FAQ.