Hi,
I have an array double[] MyArray (32 bits) and a variable ushort MyDevice (16 bits).
I wish to load the ushort MyDevice 16 bits to the upper 16 bits of the double[] MyArray
without affecting the lower array bits, but I get casting errors.
(Both work in C++) but not in C# (it's too safe!).
Have tried:
MyArray[1] |= MyDevice << 16;
and
MyArray[1] & 0xFFFF0000 = MyDevice;
I get errors in both cases.
Can anyone advice?
Thanks
Loading
Sam HobbsPosted Dec 24, 2011, 11:19 PM
Note that my code copies the bytes of the double d to a byte array (dbytes). Then it copies the bytes of the UInt16 ui to a byte array (uibytes). Then it copies the two bytes of the UInt16 to the first two bytes of the double. Then it converts dbytes to a double.
Wait; what did I say? I said that we alter the first two bytes of the double and get a double. Did you see that? We have a (data type) double in and a double out.
Again, please stop thinking that a double is 32 bits.
I have not looked at Vulpes's code but I assume it is a possible solution.
I however am very skeptical of the design of what you are trying to do. You have an array of doubles in which you want to store other data in place of some of the doubles. That does not sound good. Another possibility is to create a base class and then derive classes from that. Then you can create an array of the base class but set each item of the array to one of the derived classses. The derived classes can have different members.
{DataDouble dd;////DataUi dui;////{{else{else{VulpesPosted Dec 25, 2011, 2:14 PM
But, no matter, if you're fairly happy with your own solution.
A merry Christmas to you too :)
SamPosted Dec 25, 2011, 7:20 AM
Thanks to Vulpes and Sam Hobbs for your significant efforts to help.
I considered and tested both proposals, both seem to be viable and good solutions.
I have learned a lot, and will surely use it sometime in the future.
Yet, IMHO both are quite complex (time and space consuming) to achieve my humble goal, namely to save some space on the array.
The main problem is that my array is relatively large: It is 128 fp cells, and may grow to 256. IMHO, both proposed solutions seem to be good for small array (Am I right?).
I found a compromise solution that is programmatic 'ugly' and does not save all the available space, but is reasonable and easy to implement.
Using a float array to keep one 16 bit is straightforward. I can therefore store either one 16 bit int or two bytes in one fp space (Using the fp 23 mantissa bits, and get some 7 spare bits!).
Load to array:
array[n] = byte2 + (byte1 << 8);
Read from array:
byte1 = ((uint)array[n] >> 8) & 0xFF);
byte2 = ((uint)array[n] & 0xFF);
One disadvantage is that when loading the data, one must always combine and load both bytes together. (could not find a way to use |= or & with fp in loading).
Its not nice, and not all I wanted, but a fair compromise.
To all of you who celebrate Christmas - Marry Christmas, and to all of us - A happy new 2012!
Sam
VulpesPosted Dec 24, 2011, 11:04 AM
SamPosted Dec 24, 2011, 10:12 AM
First - Yes, Vulpes, bit operation works on int, but at the end, everything is bits, and the question is how to convert the more complex number types into bits and bytes.
I thought about Sam Hobbs proposed solution and tried it.
The BitConverter is a tool for breaking down an int 32 (or any) size into bytes, but it does not change the nature of the type.
A float remains float, which means (as I found out) it modifies the bytes entered to float. I can not see how I can use it to write bytes (or bits) to a float (or other) and read them back unaltered.
After endless experiments and tries, I am still confused.
Here is the goal:
I have an embedded application with limited memory.
I have a large float array in which I keep various values.
Some cells are not in use, and I wish to use them to keep several non-related bytes and double-bytes.
In principle, as each array cell holds 32 bits (in float format), I thought I could convert certain cells to UInt32 and use them as I wish. (after all, regardless of the type, they are only simple 32 bits structures).
I then want to be able to manipulate any of the 4 bytes without affecting the other bytes.
I have done this with a generic C++ (Non .NET), and it worked well like this (with some basic casting):
(uint32)MyArray[1] |= MyDevice << 16; (Here I replace the upper 16 bits, but it can be done to any number of bits, in any location).
C# does not accept the |= operation due to the types mismatch.
I can do chan_param[1] = DeviceID << 16; but this is no good: It still interpret the array as float (I don't care), but it will also push out my lower bytes.
The question is:
How to convert the Float[x] into simple UInt32 that has no formatting, which will allow bits manipulation.
I then need to save it back to the array without being formatted to float, and then read it back from the array, without being changed.
And, if possible, manipulate any byte or bit individually.
I am quite sure there is a direct or a workaround, but I don't know how.
I will keep trying, bu will appreciate any help.
Thanks
Sam
Sam HobbsPosted Dec 24, 2011, 5:11 AM
I agree with Vulpes that the question is very confusing. In addition to the fact that a double is 64 bits, we can easily be confused about what is the upper and what is the lower bits. Intel processors store numbers byte-by-byte in reverse order than we expect so it is easy to get confused.
The following code will copy the 2 bytes in a UInt16 to the first two bytes of a duble. I know you say you have an array of doubles and this shows just one double. If this does not help then please clarify what you need.
VulpesPosted Dec 23, 2011, 1:12 PM
Also double requires 64 bit of storage, rather than 32, and is stored in a totally different format to integers. The result of manipulating its individual bits would therefore be difficult to predict.
Are you sure that you don't want to load the upper 16 bits of an int (or uint) which does require 32 bits of storage?