Hi,
This is my C++ problem. I get back a short array from a system-call that's dedicated to system I work on. The short array somewhere contains an 8-byte long numeric value. How do I get this 8-byte numeric value in a suitable C++ datatype (double I think ?).
Here's the problem in simplified sample-code.
A double is not the right type for this. You are looking for an 8 byte unsigned int value. Does your system provide an 8 byte int? In C++, I think unsigned long long is guaranteed to be able to hold up to the value 18446744073709551615, but off the top of my head I'm not certain.
#include <iostream>
#include <limits>
usingnamespace std;
int main()
{
shortint result[20];
result[10] = 0;
result[11] = 0;
result[12] = 1269; // binary 0000010011110101
result[13] = 29346; // binary 0111001010100010
unsignedlonglong x = 0;
unsignedlonglong mult = 0xFFFFFFFFFFFFULL; // To get the big value as an unsigned long long
x = x + result[10]*mult;
x = x + result[11]*0xFFFFFFFF;
x = x + result[12]*0xFFFF;
x = x + result[13];
cout << x << endl;
// max val test
result[10] = 65535;
result[11] = 65535;
result[12] = 65535;
result[13] = 65535;
x = x+result[13];
x = x+(result[12]*65535); // 65535 = b 1111 1111 1111 1111
x = x+(result[11]*4294967295); // 4294967295 = b 1111 1111 1111 1111 1111 1111 1111 1111
x = x + result[10]*mult;
cout << x << endl;
}
In addition to what moschops suggested, there are a several other ways to do this. These methods are non-portable, but so the the OS call.
For methods 1 and 2, you need to be sure of the alignment rules for your hardware. If the alignment rules for your hardware require that an int64 be aligned on an 8 byte bounday (common) than this won't work, since the int64 is not aligned on an 8 byte bounday.
1) Declare a struct.
1 2 3 4 5 6
typedeflonglong int64; // if needed
struct os_result
{ short rslt1[12];
int64 what_i_want;
short filler1[4]; // needed to pad out to 20 words
} result;
You would probably need to cast the address of the struct to a short pointer to pass to the OS call.
2) Address calcuation
1 2 3 4
short result[20];
int64 * p_what_i_want; // typedef as before if needed
p_what_i_want = (int64 *) &result[12];
cout << *p_what_i_want << endl;
Again hardware alignment rules may preclude this.
3) Copy bytes
1 2 3
short result[20];
int64 what_i_want;
memcpy (&what_i_want, &result[12], sizeof(what_i_want));
Hardware alignment would not be a consideration here.
I didn't see your second post as you made that while I was typing.
I know Guardian well. Have been working on Guardian for many many years.
Getting an array of shorts back from an OS call certainly sounded like Guardian. :)
Sounds like you're getting a 64 bit eof as one of the items back from FILE_GETINFOLIST_.
The code you posted in your second post will work as you indicated, but it does so at the expense of an address alignment trap. i.e. The NonStop firmware will detect the assignment of a non-aligned 8 byte item and will execute a firmware 8 byte non-aligned move instead of a simple quad word store. No biggie if you're only doing that once, but that's not something you want to do in a compute intensive loop.
:-))) ... well what a coincidence ;-) ... the same overhere, many many years developing on NonStop, but uptill now everything except C++ ... and not so deep that I know what the firmware is doing ;-)
Then you probably also have that NonStop attitude towards coding ;-)
It is indeed a FILE_GETINFOLIST_ variant ... I already changed it to the memcpy. I'm making a few classes just to show my client how C++ could make life easier. F.e. the FILE_GETINFO variants (4 of them) are now hardcoded in dozens of programs ... whereas a somewhat intelligent FILEINFO-class could do all the work ... and pass back info via boolean getters instead testing all kinds of hardcoded values. I'm enthousiastic about it :-).
How about you ? ... how long C++ on guardian ? ... enthousiastic ? ... they say performance is a downside of C++, is that your experience ?
What I like about C++ on Tandem is that I can provide a DLL with class wrappers for most Guardian "objects". I know that users of the classes in the DLL will be accessing the Guardian calls correctly and don't have to know the ins and outs of the Guardian calls themselves. I have perhaps 150+ classes including SPI interfaces, EMS distributor and collector interfaces, DDL Dictionary interfaces, dynamic SQL/MP interfaces, low level Guardian classes such as PHANDLE and FNAME, etc.
Very enthusiastic about C++ on Tandem. Been writing C++ on Tandem for 10+ years. With well designed classes, I find performance to be equivalent to what I could write in pTAL.
Good to hear that there is no performance penalty.
Would be interesting to share some business details ? If so, please send me a private message with your emailadress (I can't send you one because it's turned off in your profile).