Hello,
When working on parabolic interpolation in a Pd class, I wondered again what is the best method to specify literal constants as Pd's type t_float (which could be float or double). The interpolation goes like:
...
t_float a = buf[peakindex-1];
t_float b = buf[peakindex];
t_float c = buf[peakindex+1];
t_float realpeak;
realpeak = b + 0.125 * (c - a) * (c - a) / (2. * b - a - c);
...
Without float suffixes for the literals, single precision t_float variables would be promoted to double here, which would be an unintended waste of CPU cycles. For some time, I've worked around this by using const variables instead of literals, like:
...
const t_float two = 2.;
const t_float eighth = 0.125;
t_float a = buf[peakindex-1];
t_float b = buf[peakindex];
t_float c = buf[peakindex+1];
t_float realpeak;
realpeak = b + eighth * (c - a) * (c - a) / (two * b - a - c);
...
While this avoids redundant type conversions, it clutters the code and does not result in such fast instructions as literals do. Therefore I am now using type casts where type specifiers are normally used:
...
t_float a = buf[peakindex-1];
t_float b = buf[peakindex];
t_float c = buf[peakindex+1];
t_float realpeak;
realpeak = b + (t_float)0.125 * (c - a) * (c - a) / ((t_float)2. * b -
a - c); ...
For the above code I have checked assembly output as generated by GCC with -O3 optimization on Linux i386. Using literals without type specification, the whole routine is done on the FPU (80 bits precision). With the literals cast to t_float, it is done with single precision instructions for XMM registers.
As far as I can see, casting literals to t_float results in the same assembly output as using the float specifier. For single precision t_float, '(t_float)0.125' is equivalent to '0.125f'. I can't think of a disadvantage, but let me know if I overlooked something.
Katja