2
votes

I have the following line of codes to calculate the percentage of count/total.

In Microsoft Visual C++ 2005

printf("Count = %lu (%.2lf%%)\n", count, (double)count/(double)total*100.0);

In gcc

printf("Count = %lu (%.2lf\%)\n", count, (double)count/(double)total*100.0);

Both "count" and "total" are unsigned 64-bit integers. For some reason, I'm able to get the correct value in gcc, but always get 0.00% in Visual C++.

Why can't I get the correct value in Windows?

1

1 Answers

2
votes

%lu prints an unsigned long int. In Visual C++, that's a 32-bit integer, not a 64-bit integer. You said that "count" is a 64-bit integer, so it is not a "long int". (You must have declared it as __int64 count; or long long int count;, right? How else would you declare a 64-bit integer variable in Visual C++ 2005?)

Since printf has no idea what arguments you've passed or how big they are, it relies on the format string to tell it how many bytes of data to pull off the stack for each argument. By writing %lu, you've told it to remove 4 bytes (32 bits) of data for "count", but you passed 8 bytes (64 bits) of data when you passed the 64-bit integer variable "count" to printf. That leaves 4 bytes still sitting on the stack. Then when printf goes to remove the 8 bytes (64 bits) of "double" for the percentage, it first ends up with 4 bytes leftover from "count". Since Intel x86 CPUs are little-endian, those bytes are almost certainly 00000000.

Short answer: write %I64u or %llu to print an unsigned 64-bit value in Visual C++.