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?
%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++.
Related
in vim :h Number:
Number A 32 or 64 bit signed number.
the value of max 32/64bit number:
2^31=2147483648
2^63=9223372036854775808
Now if I call str2nr() in vim:
:echo str2nr('2147483648')
-> -2147483648
:echo str2nr('112147483648')
-> 478333952
or eval the expression directly:
echo 2147483648 + 7777
-> -2147482871
So the question is, vim doc tells number is 32 or 64 bit number. How to make vim handle the 64bit number? like 2147483648 + 7777 =2147491425
P.S above test was done on:
Archlinux 64bit
Vim 7.4.135 (from Arch 64bit repo)
According to this https://groups.google.com/forum/#!topic/vim_dev/2pXdRG7yW0Y. You can't.
Bram says that a number is an int and if your platform declares int as having 64 bits you will have a 64 bit int in vim. However int was chosen to be 32 bits (by your compiler), so you only get 32 bits for a number.
In :h limits I find the following.
Range of a Number variable: -2147483648 to 2147483647 (might be more on 64
bit systems)
The might be more is probably telling you that those limits might still be the same on a 64 bit platform. It is totally up to the compiler.
I think the only way you would be able to change this is if you were to go through all of the source code and change how numbers are represented internally or find a compiler that represents int as 64 bits. (I don't know of one off hand)
If you want to find out how many bits your compiler will represent an int as you can run the following code.
#include "limits.h"
#include "stdio.h"
int main() {
printf("sizeof int in bits %lu\n", sizeof(int) * CHAR_BIT);
}
On my 64 bit machine this prints (I suspect your machine will do the same)
sizeof int in bits 32
While, for example, perldata documents that scalar strings in Perl are limited only by available memory, I'm strongly suspecting in real life there would be some other limits.
I'm considering the following ideas:
I'm not sure how strings are implemented in Perl — is there some sort of byte/character counter? If there is, then probably it's implemented as a platform-dependent integer (i.e. 32-bit or 64-bit), so effectively it would limit strings to something like 2 ** 31, 2 ** 32, 2 ** 63 or 2 ** 64 bytes.
If Perl doesn't use a counter and instead uses some byte to terminate the string (which would be strange, as it's perfectly ok to have a string like "foo\0bar" in Perl), then all operations would inevitably get much slower as string length increases.
Most string functions that Perl deals with strings, such as length, for example, return normal scalar integer, and I strongly suspect that it would be platform-limited integer too.
So, what would be the other factors that limit Perl string length in real life? What should be considered an okay string length for practical purposes?
It keep track of the size of the buffer and the number of bytes therein.
$ perl -MDevel::Peek -e'$x="abcdefghij"; Dump($x);'
SV = PV(0x9222b00) at 0x9222678
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x9238220 "abcdefghij"\0
CUR = 10 <-- 10 bytes used
LEN = 12 <-- 12 bytes allocated
On a 32-bit build of Perl, it uses 32-bit unsigned integer for these values. This is (exactly) large enough to create a string that uses up your process's entire 4 GiB address space.
On a 64-bit build of Perl, it uses 64-bit unsigned integer for those values. This is (exactly) large enough to create a string that uses up your process's entire 16 EiB address space.
The docs are correct. The size of the string is limited only by available memory.
I am new in vc++... I have one doubt in vc++. what is the size of GetTickCount() function.The return type of GetTickCount() is DWORD. Please anyone Answer for my question.
Thanks in Advance
The size of a function means the number of bytes occupied by the code that belongs to the function. You can find this out using a debugger like Windbg. But this is not useful information in most cases. To get the size of a data type, you can use the sizeof operator. Since the return type of GetTickCount is DWORD (4 bytes), you can either do sizeof(DWORD) or sizeof(GetTickCount()) to get its size. There is also a function by the name GetTickCount64 which returns ULONGLONG which is a 64-bit unsigned value (8 bytes).
GetTickCount() returns a DWORD which is 4 bytes. The function itself can be represented using its start address (function pointer) which will have size equal to size of void* which is 4 bytes on 32-bit systems and 8 bytes on 64-bit systems. Finding the size of code that the function occupies can be problematic and is rarely needed.
The Linux printf renders %p arguments as hex digits with a leading 0x. Is there a way to make it not print the 0x? (Needs to work on both 32 and 64 bit.)
You can use the format specifier for uintptr_t from <inttypes.h>:
#include <inttypes.h>
[...]
printf("%"PRIxPTR"\n", (uintptr_t) p);
This works like %x for the uintptr_t type, which is an integer type capable of roundtrip conversion from/to any pointer type.
Use %llx, it will work on 64-bit for sure. Tried and tested.
Use %lx or %08lx. It works for both 32 and 64 bit linux gcc, because long int is always the same width as void *. Doesn't work for MSVC, because long int is always 32 bit in MSVC.
If you want it to work on all compilers, you can use %llx and cast your pointer to unsigned long long int, it's not efficient in 32 bit though.
If you want efficiency as well, define different macro for different cases.
Just noticed something that looks strange to me. Visual C++ doesn't align object in their required boundary by default. For example long long is aligned to 4 bytes boundary, while __alignof(T) returns 8 (as far as I see it always returns size of the type). So it looks like it is not properly aligned. For example
long long a1;
char g;
long long a2;
// alignment check for &a2 fails
if (((uintptr_t)&a2 & (__alignof(long long) - 1)) != 0) // failed
I also tried just to print the pointer, the value of &a2 is 0x0035F8FC(3537148 in dec).
Is there something I get wrong? I need properly aligned object of type long long. What can I do about that?
I could use __declspec(align()) Microsoft extension, but it requires literal number, so I can't write anything like that.
__declspec(align(__alignof(long long))) long long object;
VC doesn't guarantee automatic stack alignment of variables, at most the variable will be aligned to the stacks alignment(generally 4 bytes on 32 bit systems). If you need special alignment, you need to use __declspec(align(x)), just like MSVC's SSE types(like __m128), else you'll need to use _aligned_malloc instead
The alignment should minimize the memory cycles on RAM access. The 4 byte alignment uses only two 32-bit acccesses to the long long. The 8 byte aligment doesn't improve the behavior. The compiler has a default alignment that can be overwritten with the /Zp option.
See also: Configuration Properties C/C++ Code Generation Struct Member Aligment.