short array to ??

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.

short result[20];
result[10] = 0;
result[11] = 0;
result[12] = 1269; // binary 0000010011110101
result[13] = 29346; // binary 0111001010100010

So how do I get above 8 bytes (value 83194530) in a double ? Or should I use another datatype (as the max.value = 18446744073709551615) ?

Thanks !
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.


Edit: Here's some demo code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <limits>


using namespace std;

int main()
{
short int result[20];

result[10] = 0;
result[11] = 0;
result[12] = 1269; // binary 0000010011110101
result[13] = 29346; // binary 0111001010100010

unsigned long long x = 0;
unsigned long long 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;
}

Last edited on
I looked it up. An int is 32 bits, so 4 bytes. It's a 'long long' that's 8 bytes.
I did it like this (and it works) :

long long* p;
long long size;
p = (long long*)&result[resultI];
size = *p;
Does your system support type long long or int64?

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
typedef long long 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.

Out of curiosity, what OS are you working on?

Address calculation, that is what I do now (see my second post).

The memcpy would also be an alternative (less lines of code, and no need to declare a pointer).

I'm working on Guardian (but you problably don't know it ? ... it's the OS of HP NonStop systems).

long long is supported, I looked it up in the docs and it compiles. int64 doesn't compile.

Thanks for your posts.
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).
Topic archived. No new replies allowed.