0

Ok so for the program I'm working on, I have a section where I have 8 bytes put aside as a sort of accumulator. Throughout various points in the program I intend to use these as both a double float and a long int. At other points I intend to only use the first 4 bytes as a single int or float, and completely ignore the rest.

Similarly I also have a large array of integers where I will at some points want to read out individual 4 byte blocks, as either an integer or float. Or seamlessly smush 2 together as an 8 byte long or double.

I'm working in an environment where although my operations are incredibly simple, time and memory are incredibly scarce so I can't use up extra assignment operations copying into a separate stack variable. I'm currently working in c but am near enough into the project I can easily start over in a new language if this isn't the best for it. How might I go about doing this. If I have a double variable, or an array of integers, how can I arbitrarily read variables as other data types without doing any conversion, any computational overhead, even when the type sizes don't match. Thankyou

1 Answers1

0

Use unions. Unions are designed for memory to be used as different types at different times.

Ok so for the program I'm working on, I have a section where I have 8 bytes put aside as a sort of accumulator. Throughout various points in the program I intend to use these as both a double float and a long int. At other points I intend to only use the first 4 bytes as a single int or float, and completely ignore the rest.

Definition:

union { double d; long int l; int i; float f; } Accumulator;

Uses:

Accumulator.d = 3.4;
Accumulator.l = -3;
Accumulator.i = 7;
Accumulator.f = 3.4f;

Similarly I also have a large array of integers where I will at some points want to read out individual 4 byte blocks, as either an integer or float. Or seamlessly smush 2 together as an 8 byte long or double.

Definition:

#define N 1024
union { int i[N]; float f[N]; long l[N/2]; double d[N/2]; } LargeArray;

Uses:

LargeArray.i[j] = 7;
LargeArray.f[j] = 3.4f;
LargeArray.l[j] = 7l;
LargeArray.d[j] = 3.4;

Note that storing into different elements of the several arrays in the union has some language-lawyer issues with regard to the C standard, but I would expect it to work in current common C implementations. These could be avoided by making an array of unions instead, but then you would have to do some additional arithmetic. For example, LargeArray.i[j] would become LargeArray[j/2].i[j%2]. The union definition would become:

union { int i[2]; float f[2]; long l; double d; } LargeArray[N/2];

Additionally, it would be good to use some _Static_assert declarations to ensure the size relationships between the types are as expected.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Ah thankyou, this looks perfect. the only question I have is in the array. With the conversion between ints and longs for example, if I wanted to read a long starting at element 0 or element 2, is there anyway I cld get around the overhead of dividing(or bitshifting) the index by 2, and perhaps more importantly, what would I do if I wanted to read element 1. I can't index by .5 – slit bodmod Oct 21 '22 at 22:22
  • also how easy would it be for me to assign a pointer to an int array to a pointer of LargeArray – slit bodmod Oct 21 '22 at 23:20
  • in fact yeah how would I go about mallocing to an array like this, can I cast to an anonymous union? would I just cast to an int* or int[]*? or assigning to the stand alone variable – slit bodmod Oct 21 '22 at 23:38