0

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

5
  • 1
    The fprintf line is missing a third parameter, but you probably mis-copied that. @Charlie Please don't just add that. It might be the problem we're looking for. @JPM Is the current code the one you got? Can you reproduce the problem when setting vol = 1; instead of using atoi? Commented May 7, 2009 at 21:57
  • 1
    Given that he says it prints a negative number, i suspect it must be the printf that's wrong. If it weren't wrong, %llu would print a positive number (whatever that is is another concern) and not a negative one. Commented May 7, 2009 at 22:01
  • Well, the printf may be wrong (as opposed to miscopied), but so is atoi. Commented May 7, 2009 at 22:04
  • @JPM, try compiling with -std=c99 -pedantic . Also note that long long is C99 and C99 requires it is at least 64bit big. Commented May 7, 2009 at 22:24
  • @phihag: Sorry, I didn't think about the possibility that this really was the exact code being compiled, and that some compiler might be willing to accept it. Commented May 10, 2009 at 20:11

7 Answers 7

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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.

1 Comment

atoll is C99 only I think, it's usually available as an extension for ANSI C but only guaranteed in C99.
0

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.

Comments

0

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?

Comments

0

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.

1 Comment

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.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.