Float masking (Is there a trick?)


#1

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?


#2

Nop.
If you have a full array of those, better look at stuff like
https://software.intel.com/en-us/ipp-dev-reference-threshold


#3

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.


#4

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


#5

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>)


#6

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?


#7

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.


#9

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


#11

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


#12

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.