Encoding 0/1 bits to 0/255 bytes in C++ I need to map a sequence of bits that represents a float into a sequence of bytes by this rule: the value 1 maps to the value 255 and the value 0 maps to the value 0.

This is the code I have now:

int FloatToBit(int *buffer, int startIndex, float value) {
  int fl = *(int*)&amp;value;
  int i = 0;
  for (; i &lt; sizeof(float) * 8; ++i) {
    buffer[startIndex + i] = ((1 &lt;&lt; i) &amp; fl) != 0 ? 255 : 0;
  }
  return i;
}


The code above is working, still I need something faster. Is it possible to improve its performance?

Edit 1:
I have created an online benchmark for this function.

Edit 2:
Using buffer[startIndex+i] = (unsigned char)-((fl&gt;&gt;i)&amp;1) as @matt-timmermans suggested in the original question. Looks like there is no evident performance improvement.
Online benchmark.

Edit 3:
This benchmark shows that the approach suggested by @greybeard is ~29 times faster than the original implementation.

Edit 4:
Created a benchmark that measures all the suggested approaches.
Writing memory is s.l.o.w. - especially if writing less than the processor word/bus width.
Loop jamming has a chance to speed up things - from a distance, this is just a source code variant of the Streaming SIMD code hoffmale linked.

Instead of table lookup, one can turn LeastSignificantFirst bits in word to MSF bytes in u32 using bit manipulation - I failed to produce a readable variation taking full advantage of CHAR_BIT &amp; co.:

leastBits = ((((1&lt;&lt;CHAR_BIT)+1 &lt;&lt; CHAR_BIT)+1 &lt;&lt; CHAR_BIT)+1);
bytes = (bits &amp; 0xf) * ((((8&lt;&lt;CHAR_BIT)+4 &lt;&lt; CHAR_BIT)+2 &lt;&lt; CHAR_BIT)+1);
bytes = (bytes &gt;&gt; 3) &amp; leastBits;
bytes = (bytes&lt;&lt;CHAR_BIT) - bytes;


should work like an evil spell, even extended to eight bytes.
The problem with LSF bits to MSF bytes and no less bits to convert than bits/byte is part products running into each other - use

bytes = (bits &amp; 0xf | ((bits &amp; 0xf0)&lt;&lt;32))*0x204081;


(and no &gt;&gt; 3(7)))  

Warning tried out, but not even tested systematically.

const int NBFL = sizeof(float) * CHAR_BIT;

static void BitsToBytesImproved(benchmark::State&amp; state) {
  // Code not measured
  float value = 1000.1234567;  // Params initialization
  unsigned char * buffer0 = new unsigned char[1024];
# define BASE_TYPE long
# define UNSIGNED_TYPE unsigned BASE_TYPE
# define UNSIGNED_SIZE sizeof(UNSIGNED_TYPE)
# define UNSIGNED_BIT  (1 &lt;&lt; UNSIGNED_SIZE)
  UNSIGNED_TYPE bits = 0xff,
  *buffer = (UNSIGNED_TYPE *)buffer0,
  patterns[UNSIGNED_BIT] = { 0 };
 // set up pattern look-up table
  for (int done = 1 ; done &lt; UNSIGNED_BIT ; bits &lt;&lt;= CHAR_BIT)
    for (int i = 0, next = 2*done ; done &lt; next ; )
      patterns[done++] = patterns[i++] | bits;

  for (auto _ : state) { // this loop is measured repeatedly
    value += .1;            // to prevent static evaluation
    int fl = *(int*)&amp;value;
    for (int i = 0 ; i &lt; NBFL ; i += UNSIGNED_SIZE) {
      UNSIGNED_TYPE *pui = (UNSIGNED_TYPE *)(buffer0 + i);
      bits = patterns[fl &amp; UNSIGNED_BIT-1];
      benchmark::DoNotOptimize(*pui = bits);
      fl &gt;&gt;= UNSIGNED_SIZE;
    }
  }
}


(Benchmark results have been too ticklish to the way I put the code for me to put much trust in them. FWIW, table look-up was reported faster than bit-bashing.)