Using a float to store 16 2-bit ints

Hi!

I have some floats (they must be floats because they're used elsewhere, as they're multipurpose) that I would like to use to store 16 2-bit integers.

This would be easy enough using bitwise operators, but those are not available for floats.

Here's some simple code to demonstrate to problem:

volatile float a=0;

void setup() {
  // put your setup code here, to run once:
  a=reinterpret_cast<uint32_t>(a)>>2;
}

void loop() {
  // put your main code here, to run repeatedly:

}

With or without the reinterpret_cast, it throws an error.

I tried with union too, but there's nothing to show for it (union also wouldn't work for what I'm doing, as I need to do left- and right-shifts)

I do not want to use a uint32_t to store these variables, as I'm optimizing for size.

Any suggestions?

Fuzzyzilla:
I do not want to use a uint32_t to store these variables, as I'm optimizing for size.

Since float is 32 bits why will uint32 be worse than float ?

I am not using floats in place of uint32_t's to save size - I know they're the same. I'm using them because I need floats elsewhere.

What I'm making here is a OS with apps. The apps share a common temporary memory of 10 floats (for the reason that floats can store ints OR decimals when needed). However, in one app, I want to store 16 2-bit ints, hence why I want to recycle one of the general-purpose floats.

Thanks for the quick replies!

What I meant is I do not want to add another variable for this one app, as I cannot change the type of the floats.

Can I have a little help with that? I was unable to do it, as I said in the OP.

Should I use a union between float and uint32_t to achieve right- and left-shifts?

Sorry for my confusing posts, but thank you for the help!

for the reason that floats can store ints OR decimals when needed)

There is no such thing as a "decimal" nor con a float store an int. It's clear to me that you have no understanding of how data is stored. SO GO LOOK IT UP.

Mark

Thanks, oh so helpful sir. You see, this is why I love this forum oh so much.

I KNOW a float cannot store an int - but it comes close.

I KNOW a float cannot store a fractional number, but it comes close.

typedef union
{
  float as_float;
  struct
  {
    uint16_t thing_one;
    uint16_t thing_two;
  }
  as_struct;
  uint16_t as_array[2];
}
thirty_two_bits_of_whatever;

Alright, I think I've figured out a way using reinterpret_cast.

volatile float a=0;

void setup() {
  // put your setup code here, to run once:
  uint32_t *binary=reinterpret_cast<uint32_t>(&a);
  uint32_t value=*binary<<2;
}

void loop() {
  // put your main code here, to run repeatedly:

}

EDIT: Thanks Coding Badly! Which should I use: union or reinterpret? (if it makes any difference, I hope to migrate to a 32-bit architecture, and I know some things can have incompatibility issues)

This is untested, but it compiles at least.

Using a float to store 16 2-bit ints

If you know it can't why bloody weel ask!

Mark

Fuzzyzilla:
Which should I use: union or reinterpret?

As far as I know the only difference regards aliasing. A quick Google search indicates that union is a better choice in such matters.

However, I believe aliasing problems can only occur if you use both pointers (pointer to float and pointer to uint16_t) in the same context.

I tend to favour unions because I believe it makes the code easier to read.

(if it makes any difference, I hope to migrate to a 32-bit architecture, and I know some things can have incompatibility issues)

Packing, padding, and byte order. Three new things for you to learn.