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