manipulating LARGE_INTEGERS - c++

I am converting some code from C to C++ in MS dev studio under win32. In the old code I was doing some high speed timings using QueryPerformanceCounter() and did a few manipulations on the __int64 values obtained, in particular a minus and a divide. But now under C++ I am forced to use LARGE_INTEGER because that's what QueryPerformanceCounter() returns. But now on the lines where I try and do some simple maths on the values I get an error:
error C2676: binary '-' : 'LARGE_INTEGER' does not define this operator or a conversion to a type acceptable to the predefined operator
I tried to cast the variables to __int64 but then get:
error C2440: 'type cast' : cannot convert from 'LARGE_INTEGER' to '__int64'
How do I resolve this?
Thanks,

LARGE_INTEGER is a union of a 64-bit integer and a pair of 32-bit integers. If you want to perform 64-bit arithmetic on one you need to select the 64-bit int from inside the union.
LARGE_INTEGER a = { 0 };
LARGE_INTEGER b = { 0 };
__int64 c = a.QuadPart - b.QuadPart;

LARGE_INTEGER is a union, documented here. You probably want a QuadPart member.

Here it is:
LARGE_INTEGER x,y;
///
//Some codes...
///
__int64 diff = x.QuadPart - y.QuadPart
Because QuadPart is defined as a LONGLONG , that same as __int64.

LARGE_INTEGER is a union, you can still use .QuadPart if you want to work on the 64-bit value.

As the Documentation says in the Remarks section :
The LARGE_INTEGER structure is actually a union. If your compiler has built-in support for 64-bit integers, use the QuadPart member to store the 64-bit integer. Otherwise, use the LowPart and HighPart members to store the 64-bit integer.
So if your compiler supports 64 bit integers use quadPart like this :
LARGE_INTEGER a, b;
__int64 diff = a.QuadPart - b.QuadPart

In addition to the answers, if you are looking to construct a LARGE_INTEGER with a value other than zero, you can assign the low and high parts separately. LowPart is first as defined in the union, and the only highPart is signed.
LARGE_INTEGER li = {0x01234567, -1};

Related

Strange behaviour of 64 bit integer in C++

I'm quite new to programming, I have recently learnt a little C++ and I am using Visual Studio 2017 Community version.
I need to use a 64 bit integer to store a value and carry out some arithmetic operations, however my compiler only allows me to use 32 bits of the "int64" variable I have created.
Here is an example of some code and the behaviour
unsigned __int64 testInt = 0x0123456789ABCDEF;
printf("int value = %016X\n", testInt); // only 32 bits are being stored here? (4 bytes)
printf("size of integer in bytes = %i\n\n", sizeof(testInt)); // size of int is correct (8 bytes)
The value stored in the variable seems to be 0x0000000089ABCDEF.
Why can I not use all 64 bits of this integer, it seems to act as a 32 bit int?
Probably I'm missing something basic, but I can't find anything relating to this from searching :(
It would be nice if it were just something basic, but it turns out that 64 bit ints are not dealt with consistently on all platforms so we have to lean on macros.
This answer describes the use of PRIu64, PRIx64, and related macros included in <inttypes.h>. It looks funny like this, but I think the portable solution would look like:
#include <inttypes.h>
unsigned __int64 testInt = 0x0123456789ABCDEF;
printf("int value = %016" PRIX64 "\n", testInt);
The PRIX64 expands to the appropriate format specifier depending on your platform (probably llX for Visual Studio).
Format specifier %X takes an unsigned int (probably 32 bit on your system), whereas __int64 corresponds to long long.
Use printf("int value = %016llX\n", testInt) instead. Documentation can be found, for example, at cppreference.com.

Concise bit-manipulation for 64bit integer handle type

I have a 64bit integer that is used as a handle. The 64bits must be sliced into the following fields, to be accessed individually:
size : 30 bits
offset : 30 bits
invalid flag : 1 bit
immutable flag : 1 bit
type flag : 1 bit
mapped flag : 1 bit
The two ways I can think of to achieve this are:
1) Traditional bit operations (& | << >>), etc. But I find this a bit cryptic.
2) Use a bitfield struct:
#pragma pack(push, 1)
struct Handle {
uint32_t size : 30;
uint32_t offset : 30;
uint8_t invalid : 1;
uint8_t immutable : 1;
uint8_t type : 1;
uint8_t mapped : 1;
};
#pragma pack(pop)
Then accessing a field becomes very clear:
handle.invalid = 1;
But I understand bitfields are quite problematic and non-portable.
I'm looking for ways to implement this bit manipulation with the object of maximizing code clarity and readability. Which approach should I take?
Side notes:
The handle size must not exceed 64bits;
The order these fields are laid in memory is irrelevant, as long as each field size is respected;
The handles are not saved/loaded to file, so I don't have to worry about endianess.
I would go for the bitfields solution.
Bitfields are only "non-portable" if you want to store the in binary form and later read the bitfield using a different compiler or, more commonly, on a different machine architecture. This is mainly because field order is not defined by the standard.
Using bitfields within your application will be fine, and as long as you have no requirement for "binary portability" (storing your Handle in a file and reading it on a different system with code compiled by a different compiler or different processor type), it will work just fine.
Obviously, you need to do some checking, e.g. sizeof(Handle) == 8 should be done somewhere, to ensure that you get the size right, and compiler hasn't decided to put your two 30-bit values in separate 32-bit words. To improve the chances of success on multiple architectures, I'd probably define the type as:
struct Handle {
uint64_t size : 30;
uint64_t offset : 30;
uint64_t invalid : 1;
uint64_t immutable : 1;
uint64_t type : 1;
uint64_t mapped : 1;
};
There is some rule that the compiler should not "split elements", and if you define something as uint32_t, and there are only two bits left in the field, the whole 30 bits move to the next 32-bit element. [It probably works in most compilers, but just in case, using the same 64-bit type throughout is a better choice]
I recommend bit operations. Of course you should hide all those operations inside a class. Provide member functions to perform set/get operations. Judicious use of constants inside the class will make most of the operations fairly transparent. For example:
bool Handle::isMutable() const {
return bits & MUTABLE;
}
void Handle::setMutable(bool f) {
if (f)
bits |= MUTABLE;
else
bits &= ~MUTABLE;
}

What is the point of the ULARGE_INTEGER union?

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383742%28v=vs.85%29.aspx
They are supposed to be used like this, set two 32 bit values on LowPart and HighPart and then perform arithmetic on the QuadPart.
int a,b,c;
ULARGE_INTEGER u;
...
u.LowPart = a;
u.HighPart = b;
u.QuadPart += c;
So if you are going to perform arithmetic on the QuadPart(64 bits) anyways you need a 64 bit processor, right? So what is the whole point? Why not assign the value directly to the QuadPart?
You don't need a 64 bit processor to perform arithmetic on a 64 bit data type. All 32 bit compilers that I know of support arithmetic on 64 bit integers. If the hardware doesn't allow native arithmetic, then the compiler has to generate code to do the arithmetic. Typically this will make use of support functions in the compiler's RTL.
The struct is intended for use by compilers that don't provide native support for 64 bit data types. The very documentation to which you linked makes that clear:
Note Your C compiler may support 64-bit integers natively. For
example, Microsoft Visual C++ supports the __int64 sized integer type.
For more information, see the documentation included with your C
compiler.
Compilers that don't support native 64 bit integers will not be able to treat the QUADPART union member as an integer.
typedef union _ULARGE_INTEGER {
struct {
DWORD LowPart;
DWORD HighPart;
};
struct {
DWORD LowPart;
DWORD HighPart;
} u;
ULONGLONG QuadPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;
And the definition of ULONGLONG:
#if !defined(_M_IX86)
typedef unsigned __int64 ULONGLONG;
#else
typedef double ULONGLONG;
#endif
Of course, all compilers written in the past 10 years (or more) will have native support for 64 bit integers. But this union was originally introduced a very long time ago and the compiler landscape would have been different then. When looking at Windows header files, always bear in mind the history and legacy.
Typically ULARGE_INTEGER is used when you need to convert a pair of 32-bit integers into a 64-bit integer or vice-versa.
For example, consider manipulating a FILETIME structure:
void add_millisecond(FILETIME * ft)
{
ULARGE_INTEGER uli;
uli.LowPart = ft->dwLowDateTime;
uli.HighPart = ft->dwHighDateTime;
uli.QuadPart += 10000;
ft->dwLowDateTime = uli.LowPart;
ft->dwHighDateTime = uli.HighPart;
}
You can't assign the QuadPart value directly because you don't have it; all you have is the high and low parts.
So if you are going to perform arithmetic on the QuadPart(64 bits)
anyways you need a 64 bit processor, right?
No. But the real question should be, do you need a compiler that supports a 64 bit integer type? The answer to that too, in this case, is no. That's what these functions are for:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383711%28v=vs.85%29.aspx

uintmax_t for vector indexes

I am dealing with basically a bit-flag search mask and I'm using vectors. These indexes need to go up to the max integer on the machine (defined in stdint.h)
Basically the problem is
searchMask[ UINTMAX_MAX] = false; // or any value > unsigned int
results in the following warning
warning: C4244: 'argument' : conversion from 'uintmax_t' to 'unsigned int',
possible loss of data
I have considered just using something like an unsigned char* = "1110010..." and just flipping the bits that way, but dealing with C-strings is always a pain and I suspect accessing the char array index will have this same size problem?
Can I make the indexes of the vector go off the uintmax_t, or should I go the C string route, or what?
Practically all the STL containers will use size_t as their size types. So, depending on your system, size_t might be defined as an unsigned int, which will probably be a 32-bit integer in your case. That would explain why the compiler is complaining.
UINTMAX_MAX is defined as UINT64_MAX, so it won't fit in a 32-bit integer. Try using the UINT32_MAX macro, or be platform-independant and use std::numeric_limits<size_t>::max().
Also, try using std::bitset<N>.

Setting up 64 bit variables in C++

I'm wondering how to set a 64-bit variable in C++ for my testbench. When I use the variable_name.io_int_write(0,value0) and variable_name.io_int_write(1,value1) (for the lower & upper bits) I can see the variables are set but in the reverse manner.
Ex: When I want it to be 000...002, I see 200...000
Is there an alternate command that would help? Thanks
Edit: I have a function void set_function (set_ * dut)
and inside this function, I need to set a 64-bit variable dut->variable_name
Thanks for your answers, how would I go about fixing the Endianness in this case
If you want to set a 64bit integer variable to a constant value, you can simply say something like:
long long var64bit = 1L;
The L at the end of 1L says that it is a 64bit constant value of 1.
If you are comfortable with hexadecimal and want a 64bit bit-field constant, then the usual way of setting a 64bit variable would look something like this:
unsigned long long bitfield64bit = 0xDEADBEEFDEADBEEFL;
Again, note the trailing L.
If you have two 32bit values that you want to pack into a 64bit value, then you can do this using shift and logical-OR operations as:
long long var64bit = (long long)(((unsigned long long)high_bits << 32) | (unsigned long long)low_bits);
where *high_bits* is the 32bit variable holding the high bits and *low_bits* is the 32bit variable containing the low bits. I do the bit-wise operations on unsigned values because of possibly excess paranoia regarding the sign bit and conversion between 32bit and 64bit integers.
The opposite operations, dividing a 64bit variable into high and low bits can be done as follows:
int high_bits = (int)(var64bit & 0xFFFFFFFFL);
int low_bits = (int)((var64bit >> 32) & 0xFFFFFFFFL);