tags:

views:

244

answers:

7

I have an unsigned long long that I use to track volume. The volume is incremented by another unsigned long long. Every 5 seconds I print this value out and when the value reaches the 32 bit unsigned maximum the printf gives me a negative value. The code snippet follows:

unsigned long long vol, vold;
char               voltemp[10];

vold = 0;

Later...

while (TRUE) {
    vol = atoi(voltemp);
    vold += vol;    
    fprintf(fd2, "volume = %llu);
}

What am I doing wrong? This runs under RedHat 4 2.6.9-78.0.5.ELsmp gcc version 3.4.5

A: 

Well I can't really tell because your code has syntax errors, but here is a guess:

vol = atoi(voltemp);

atoi converts ascii to integer. You might want to try atol but that only gets it to a long, not a long long.

Your C standard library MIGHT have atoll.

Unknown
A: 

You can't use atoi if the number can exceed the bounds of signed int.

EDIT: atoll (which is apparently standard), as suggested, is another good option. Just keep in mind that limits you to signed long long. Actually, the simplest option is strtoull, which is also standard.

Matthew Flaschen
atoll is C99 only I think, it's usually available as an extension for ANSI C but only guaranteed in C99.
dreamlax
dreamlax, looks like you're right.
Matthew Flaschen
A: 

Are you sure fprintf can take in a longlong as a parameter, rather than a pointer to it? It looks like it is converting your longlong to an int before passing it in.

T.E.D.
+1  A: 

Since you say it prints a negative value, there must be something else wrong, apart from your use of atoi instead of strtoull. A %llu format specifier just doesn't print a negative value.

It strongly looks like the problem is the fprintf call. Check that you included stdio.h and that the argument list is indeed what is in the source code.

Johannes Schaub - litb
A: 

I'd guess the problem is that printf is not handling %llu the way you think it is. It's probably taking only 32 bits off the stack, not 64.

%llu is only standard since C99. maybe your compiler likes %LU better?

AShelly
A: 

For clarification the fprintf statement was copied incorrectly (my mistake, sorry). The fprintf statement should actually read:

 fprintf(fd2, "volume = %llu\n", vold);

Also, while admittedly sloppy the maximum length of the the array voltemp is 9 bytes (digits) which is well within the limits of a 32-bit integer.

When I pull this code out of the program it is part of and run it in a test program I get the result I would expect which is puzzling.

This clarification would be very helpful as part of the question itself. Please consider editing your question to include it instead of leaving it here as an answer.
Nathan Kitchen
A: 

If voltemp is ever really big, you'll need to use strtoull, not atoi.

Norman Ramsey