Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
0 user currently in Programming. | 3 guests
Acmlm's Board - I2 Archive - Programming - 64-bit integers in C? | |
Pages: 1 2Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 3149/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 02-09-05 07:12 AM Link | Quote
Seem to have come across a bit of a problem here... I need a 64-bit integer, but I can't find any! Using MinGW, Long, Int and Double all only seem to be able to hold values up to ~4 billion, where I need them to be as much as 10 or even 20 billion. (They're total file sizes for really big groups of files. ) Is there some way to force it to use 64-bit, or some other type of variable?
Dish

Spiny
Level: 38

Posts: 270/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 02-09-05 07:18 AM Link | Quote
I don't know if there's a standard variable for 64-bit vars. If there is... I would assume it's "long int".. though I have memories of that not working. When I need them in VS, I use "__int64", although I'm almost certain that wouldn't work in other compilers.

Find whatever one works... but instead of using it directly, typedef it to something else so that if you (or anyone else) ever needs to use a different compiler, all they have to do is change the typedef line and everything will be peachy. Something like

typedef signed __int64 s64;
or
typedef signed long int s64;


then make your vars with

s64 myVar;
Cellar Dweller

Flurry
!!!
Level: 27

Posts: 203/269
EXP: 107817
For next: 8342

Since: 03-15-04
From: Arkansas

Since last post: 16 days
Last activity: 34 min.
Posted on 02-09-05 07:34 AM Link | Quote
"long long int" should be 64 bits when using GCC.
Dish

Spiny
Level: 38

Posts: 271/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 02-09-05 07:40 AM Link | Quote
This is like the one thing I really dislike about C/C++. And ironically, they didn't change it for Java =P. They should have obvious type names which detail the size of the variable.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 3150/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 02-09-05 08:05 AM Link | Quote
Hmm... I tried "__int64 x = 5000000000;" and it seemed to recognize __int64 but still only made it 32 bits. Same thing with "long long int". It's like it doesn't realize that just because it's a 32-bit CPU doesn't mean it can't do 64-bit math (or else how could I even have files >4GB? ).

Also is there something similar to the VB 'With' statement? For example if I want to print several members of the structure "foo[i]", it's rather annoying having to type "foo[i]." before them all, and can make for rather messy code.

[edit] Bleh. Forgot [i] acts as an italics tag here.


(edited by HyperHacker on 02-09-05 04:06 AM)
neotransotaku

Baby Mario
戻れたら、
誰も気が付く
Level: 87

Posts: 2080/4016
EXP: 6220548
For next: 172226

Since: 03-15-04
From: Outside of Time/Space

Since last post: 11 hours
Last activity: 1 hour
Posted on 02-09-05 09:48 AM Link | Quote
I believe 64-bit cabability in VB and files greater than 4GB is an abstraction of the assembly code that is produced to do the work you want to be done. This is why I think doing long int doesn't work because well, 32-bits is the limit of the processors. The closest to being able to use 64-bits is in using a double.
Parasyte

Bullet Bill
Level: 35

Posts: 277/514
EXP: 267348
For next: 12588

Since: 05-25-04

Since last post: 104 days
Last activity: 32 days
Posted on 02-09-05 11:04 AM Link | Quote
unsigned long long bignum = 0x8000000000000000LL;

The LL signifies to the compiler that you are using a 64-bit constant.
neotransotaku

Baby Mario
戻れたら、
誰も気が付く
Level: 87

Posts: 2082/4016
EXP: 6220548
For next: 172226

Since: 03-15-04
From: Outside of Time/Space

Since last post: 11 hours
Last activity: 1 hour
Posted on 02-09-05 12:07 PM Link | Quote
well, what do you know... long long gives you a 64-bit manipulatable int in gcc. So, HH, you should have dropped that last "int" in "long long int"
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 3151/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 02-09-05 03:45 PM Link | Quote
Yay, it worked using Para's and Neo's ideas. Though there is still the problem that printf(), sprintf() etc still think it's 32 bits, even using %ld instead of %d.. Kinda hard to display it properly that way. (With file sizes at least, it's not entirely necessary because I don't intend to display them in bytes, but there could be times I do need to.)

And Neo, I don't recall any manner of 64-bit support in VB.

[edit] Bah, this is why I avoided C for so long. Just what the hell is wrong with assigning a constant string to a fixed-size char array? I should be able to create a constant array of strings and not have them come out as '(null)', but I must have tried every combination of brackets upon brackets, asterisks, ampersands, casts, you name it. God I hate strings.


(edited by HyperHacker on 02-09-05 12:11 PM)
jman2050

Red Koopa
Level: 19

Posts: 73/123
EXP: 33172
For next: 2605

Since: 03-21-04

Since last post: 10 days
Last activity: 103 days
Posted on 02-09-05 05:49 PM Link | Quote
THe problem is that if they are different lengths they are not the same thing. "Test string 1" is an array of 14 chars. You can't assign a char[14] array to, say, a char[80] array with direct assignment. What you need to do is use strcpy (I believe you need to include stdlib.h to use it).

strcpy (stringArray, "String constant");

With that said, you're probably going about this the wrong way anyway. I can't think of any real significant advantage to having a fixed array of chars. Just do char *string and you can assign any constant string to it you like. It is still a pointer, so do be careful with the type of assignments you do, but there really is no good reason to use fixed char arrays for strings any more...
Parasyte

Bullet Bill
Level: 35

Posts: 278/514
EXP: 267348
For next: 12588

Since: 05-25-04

Since last post: 104 days
Last activity: 32 days
Posted on 02-09-05 06:19 PM Link | Quote
Use %lld. Remember, 64-bit is LONG LONG! Single LONG just won't cut it.


As for "assigning a string to a fixed-size char array"... A string is handled in C as a pointer. Anything between two double quotes will always be a pointer to the data within the double quotes, followed by a null terminator. For example:

char *SomeString;
SomeString = "This string is actually a pointer to the data within the string. Here's the null terminator -->";

You can easily assign the pointer to SomeString, because SomeString is a pointer. An array is not a pointer. You must copy the data into the array manually. A simple assignment will not work*. Jman gave the perfect example of copying, using the strcpy() function.


* Many compilers do support assignment of strings to arrays, but only during initialization of the array. The compiler requires string.h for it to work, however. This is because the compiler litterally changes the assignment to a call to the memcpy() function. Example:

char MyString[] = "Example of 'assigning' a string to an array during array initialization.";
printf("%s",MyString);

DO NOT expect this to work everywhere. And in fact, it's probably a bad idea to use it at all, since it could cause plenty of confusion.
Here's what the created assembly looks like:

.text:004012FA        lea     ecx, [ebp+var_58]
.text:004012FD mov edx, offset aExampleOfAssig ; "Example of 'assigning' a string to an a"...
.text:00401302 mov eax, 49h
.text:00401307 mov [esp+78h+var_70], eax
.text:0040130B mov [esp+78h+var_74], edx
.text:0040130F mov [esp+78h+var_78], ecx
.text:00401312 call memcpy
.text:00401317 lea eax, [ebp+var_58]
.text:0040131A mov [esp+78h+var_74], eax
.text:0040131E mov [esp+78h+var_78], offset aS ; "%s"
.text:00401325 call printf



(edited by Parasyte on 02-09-05 02:23 PM)
(edited by Parasyte on 02-09-05 02:29 PM)
(edited by Parasyte on 02-09-05 02:48 PM)
Dish

Spiny
Level: 38

Posts: 273/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 02-09-05 08:50 PM Link | Quote
To follow up with what Para was saying... you could make an array of constant strings with the following:


const char* stringarray[3] = {
"String 1",
"String 2",
"etc"
};


Like para pointed out, whatever is in quotes will give you a pointer, so you can make an array of char pointers, each of which will point to a string.


(edited by Disch on 02-09-05 04:51 PM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 3152/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 02-10-05 12:16 AM Link | Quote
Originally posted by Disch

const char* stringarray[3] = {
"String 1",
"String 2",
"etc"
};


That's what I was looking for. I was doing it like this:
const char* stringarray[3];
stringarray[0] = "String 1";
stringarray[1] = "String 2";
[...]


I still don't see why that couldn't work, since they're constant strings; it should just be making stringarray[0] point to the first one and stringarray[1] point to the second?


...And *surprise!* it doesn't work. I really don't see why this has to be so complicated.

int unit = 0;
const char* Name[10] = {
"Bytes",
"Kilobytes",
"Megabytes",
"Gigabytes",
"Terabytes",
"B",
"KB",
"MB",
"GB",
"TB"
};
while((b >= 1024) && (unit <= 4))
{
b = b /1024;
unit++;
}
if(!FullNames) unit += 5;
sprintf(Buffer,"%d %d %s",b,unit,Name[unit]);


It still just prints null for the first one and crashes with any others. The %lld thing isn't working either:

long long x = 5000000000LL;
printf("%lld\n",x);

I still only get 705032704 (0x2A05F200) rather than 5000000000 (0x12A05F200) (whether x is signed or not).
neotransotaku

Baby Mario
戻れたら、
誰も気が付く
Level: 87

Posts: 2099/4016
EXP: 6220548
For next: 172226

Since: 03-15-04
From: Outside of Time/Space

Since last post: 11 hours
Last activity: 1 hour
Posted on 02-10-05 01:23 AM Link | Quote
Originally posted by HyperHacker
That's what I was looking for. I was doing it like this:
const char* stringarray[3];
stringarray[0] = "String 1";
stringarray[1] = "String 2";
[...]


I still don't see why that couldn't work, since they're constant strings; it should just be making stringarray[0] point to the first one and stringarray[1] point to the second?
That's because you declared the stringarray variable as const. If you didn't declare it const, then you can write to it. Think about it, if it is const, none of that memory should change but you are changing that part of memory.

as for your other code, where's the declaration of "Buffer"?

as for your long long not printing out correct, the sparc/x86 machines returned 125 billion...
Parasyte

Bullet Bill
Level: 35

Posts: 280/514
EXP: 267348
For next: 12588

Since: 05-25-04

Since last post: 104 days
Last activity: 32 days
Posted on 02-10-05 01:41 AM Link | Quote
Originally posted by HyperHacker
I was doing it like this:
const char* stringarray[3];
stringarray[0] = "String 1";
stringarray[1] = "String 2";
[...]


I still don't see why that couldn't work, since they're constant strings; it should just be making stringarray[0] point to the first one and stringarray[1] point to the second?

That will work fine. I tested it, myself:
const char* stringarray[2];
stringarray[0] = "String 1";
stringarray[1] = "String 2";
printf("%s\n",stringarray[0]);

As you expect, it prints "String 1". Nothing too surprising, here.


Originally posted by HyperHacker
...And *surprise!* it doesn't work. I really don't see why this has to be so complicated.

int unit = 0;
const char* Name[10] = {
"Bytes",
"Kilobytes",
"Megabytes",
"Gigabytes",
"Terabytes",
"B",
"KB",
"MB",
"GB",
"TB"
};
while((b >= 1024) && (unit <= 4))
{
b = b /1024;
unit++;
}
if(!FullNames) unit += 5;
sprintf(Buffer,"%d %d %s",b,unit,Name[unit]);


It still just prints null for the first one and crashes with any others.

I don't see anything explicitly wrong with that, but it could be because I'm either half asleep, or because you neglected to include some code (the code that prints Buffer, and the definition of 'b' -- even though those are not important.)


Originally posted by HyperHacker
The %lld thing isn't working either:

long long x = 5000000000LL;
printf("%lld\n",x);

I still only get 705032704 (0x2A05F200) rather than 5000000000 (0x12A05F200) (whether x is signed or not).

You may need to download and install the latest version of newlib to get it working. I believe MinGW comes with libc, rather than newlib.
Dish

Spiny
Level: 38

Posts: 274/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 02-10-05 02:07 AM Link | Quote
Originally posted by neotransotaku
That's because you declared the stringarray variable as const.


const char* somepointer;

That's a non-constant pointer to a constant char. Meaning the pointer itself isn't constant, but what it points to is.

I believe to make the pointer itself constant.. you'd do:

char* const somepointer;

So that would mean the pointer itself is constant.. but what it points to isn't. I'm not 100% sure on this, because having a pointer that's constant is really useless.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 3153/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 02-10-05 06:11 AM Link | Quote
It could be useful if you needed to write to I/O addresses or something, though not really useful, since you could just use #define instead..
Originally posted by neotransotaku
That's because you declared the stringarray variable as const. If you didn't declare it const, then you can write to it. Think about it, if it is const, none of that memory should change but you are changing that part of memory.

Er, right... It wasn't const in that.


as for your other code, where's the declaration of "Buffer"?

It's a function, actually. void FormatBytes(char* Buffer, unsigned long long Bytes, BOOL FullNames). b is just another unsigned long long that Bytes is copied into (rather than end up changing the variables that are passed... come to think of it, that wouldn't be an issue here would it?) I called it with this:
FormatBytes(TempStr,1000,true);
printf("%s\n",TempStr);

Where TempStr is a 256-byte char array. I get '1000 0 (null)' as a result. If I pass a value >=1024 for Bytes so that it would print a different string, it just crashes.

Para, I'm not sure exactly what, if anything, that code does different than mine did (I went and deleted it already), but I would just get the same result as what I have now. And maybe I just suck at Google but I can't seem to find Newlib downloads anywhere.


(edited by HyperHacker on 02-10-05 02:16 AM)
Parasyte

Bullet Bill
Level: 35

Posts: 281/514
EXP: 267348
For next: 12588

Since: 05-25-04

Since last post: 104 days
Last activity: 32 days
Posted on 02-10-05 10:16 AM Link | Quote
Wait, where did 'FormatBytes' come from? Your posts are missing far too much code, and veering off course. I can't figure out what either of those last to lines you posted has to do with any of your previous code. I would suggest pasting entire functions, and complete function calls (including definitions of variables and whatnot used therein).
Having only code snippits is causing confusion. Think of it as if you were giving these snippits to a compiler... It wouldn't know what to do, given only that information. Likewise, for any of us to compile and debug this code, we need every relevent line of code you are using.

Newlib is available here: (First link that showed up in Google. "I'm feeling lucky" would have taken you directly to it) http://sources.redhat.com/newlib/


(edited by Parasyte on 02-10-05 06:19 AM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 3155/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 02-10-05 07:09 PM Link | Quote
What, are you a compiler? I've posted all but a few lines already.

char WindowName[1024], TempStr[256];

//in WinMain()
FormatBytes(TempStr,1000,true);
printf("%s\n",TempStr);

//declaration
void FormatBytes(char* Buffer, unsigned long long Bytes, BOOL FullNames)
{
unsigned long long b = Bytes;
int unit = 0;
const char* Name[10] = {
"Bytes",
"Kilobytes",
"Megabytes",
"Gigabytes",
"Terabytes",
"B",
"KB",
"MB",
"GB",
"TB"
};
while((b >= 1024) && (unit <= 4))
{
b = b / 1024;
unit++;
}
if(!FullNames) unit += 5;
sprintf(Buffer,"%d %d %s",b,unit,Name[unit]);
}
Parasyte

Bullet Bill
Level: 35

Posts: 283/514
EXP: 267348
For next: 12588

Since: 05-25-04

Since last post: 104 days
Last activity: 32 days
Posted on 02-10-05 07:50 PM Link | Quote
There's the problem:
sprintf(Buffer,"%d %d %s",b,unit,Name[unit]);

You're passing a 64-bit variable to a format that expects 32-bit; effectively causing a nice little overflow. Each %d format will print half of 'b'. Then %s is used to print 'unit'. Obviously, %s expects a pointer. This is passing "0" as the pointer.

Now, I learned today that MinGW uses some of the native Windows DLLs for std functions (not libc or newlib, as I anticipated). Knowing this, you can head over to MSDN and look into the Microsoft printf specification. The prefix I64 (EYE-SIXTY-FOUR) can be used to print 64-bit integers:

sprintf(Buffer,"%I64d %d %s",b,unit,Name[unit]);


(edited by Parasyte on 02-10-05 03:51 PM)
Pages: 1 2Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Programming - 64-bit integers in C? | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.013 seconds.