Float masking (Is there a trick?)

Is there away to do the following with masks for float and doubles

FLOAT &= MASK // if float is positive then value the same else float is zero

FLOAT &= !MASK // if float is negative then value the same else float is zero

What would mask value be for a float and a double?

If you have a full array of those, better look at stuff like

EDIT: Not a very good example: (1) it doesn’t do what the OP wanted to do and (2) it’s not portable. I’m leaving it here for reference.

You can use the union trick:

float absoluteValue (float x)
     union {
          float f;
          uint32_t m;
      } u;

      u.f = x;
      u.m &= ~(1 << ((sizeof (float) * 8) - 1);
      return u.f;

Technically the above is undefined behaviour, but all major compilers have an exception in place to support this.

cool cheers will try out, was trying to avoid conditional statements branching as its slower on CPU but extremely slow on GPU and having masking available on both makes it a common denominator for this sort of task.

Thanks again

Yes that’s exactly where you would use these types of tricks. In fact SIMD types have special instructions for exactly this. JUCE’s SIMDRegister supports this as well. Instead of this:

auto z = (x > y ? x + (y * 2.0) : y);

you can write this:

auto mask = SIMDRegister<float>::greaterThan (x, y);
auto z = ((x + (y * 2.0)) & mask) + (y & (~mask));

(x and y are of type SIMDRegister<float>)

Is this safe on all platforms? It scares me a bit to go on assumptions about the internal representation.
E.g. the wikipedia (I know, not a scientific source) says:

Exponent is either an 8-bit signed integer from −128 to 127 (2’s complement) or an 8-bit unsigned integer from 0 to 255, which is the accepted biased form in IEEE 754 binary32 definition.

In which case it is not said, if the HSB of the exponent is actually a sign or not?

1 Like

No it’s definitely not safe on all platforms. It was rather a bad example (I was assuming x86 platform). My second example (with SIMDRegister) is better as masking/unmasking all bits will always work.

Yes that’s what I demonstrated in the second example.

I should probably just delete the first post. So much bad in one post…

Further context on why I asked the question . I have a compressor class that has that has independent peak and trough envelopes that still require a value and I didn’t want to have a condition in there as I wanted this to be usable on a gpu.

I could have achieved this with min max functions but in all cases I have tested masks just make for better performance either with SIMD or Kernels on GPUs. I should really get my head around more advanced features of floating point data as I’m sure there are other tricks I could utilise.the app im creating is very process intensive and I’m trying to get it to work realtime with low mid speeches hardware upwards.