 # bit manipulation on a float sign bit (optimize hack)

While tinkering on a faster sin(x) function - http://arduino.cc/forum/index.php/topic,69723.0.html - I noticed that negation of a float takes 1.5 micros, not very much but I use it twice in my code and 3 micros is 6.7% of my code. Then I wondered if I could just flip the sign bit with an x-or, and if so would it be faster?

So I made this sketch to test, // learned: The signbit of an arduino float is located in byte 4,

``````void setup()
{
Serial.begin(115200);
Serial.println("start");

volatile float zz = 100;

unsigned long before = micros();
for (int i=0; i< 30000; i++)
{
*(((byte*) &zz)+3) |= 0x80;  // Force negative   zz = -fabs(zz);
}
Serial.println((micros() - before)/30000.0);
Serial.println(zz);

before = micros();
for (int i=0; i< 30000; i++)
{
*(((byte*) &zz)+3) &= 0x7F;  // force positive  zz = fabs(zz);
}
Serial.println((micros() - before)/30000.0);
Serial.println(zz);

before = micros();
for (int i=0; i< 30001; i++)
{
*(((byte*) &zz)+3) ^= 0x80;  // equals  zz = -zz;
}
Serial.println((micros() - before)/30000.0);
Serial.println(zz);

before = micros();
for (int i=0; i< 30000; i++)
{
zz = -zz;
}
Serial.println((micros() - before)/30000.0);
Serial.println(zz);
}

void loop(){}
``````

output, arduino 2009 (ide22, win7/64)

start
0.75
-100.00
0.75
100.00
0.75
-100.00
1.51
-100.00

==> Yes it works! twice as fast as the normal code,

Note: remember 0.75 microsec is just 12 instructions, so use this kind of optimization only if you are as desparate for cycles as me Same way you can test if float is negative: if (zz<0)

``````zz = -100;
if (*(((byte*) &zz)+3) & 0x80) Serial.println("N");
else Serial.println("P");
``````

Agree, not the most readable code // not fully tested so all disclaimers apply