Hi,
Observe: x RELOP y ==> (x - y) RELOP 0 -1 * (x - y) ==> (y - x) i.e., (paraphrasing): -1 * [ (x - y) RELOP 0 ] ==> y RELOP x
(RELOP is ">", "=", etc.)
One of my server templates relies on this sort of thing to drive itself from tables of "constraints". E.g., sense * (trial - reference) RELOP 0 where trial and reference are **expressions** indirectly driven from the table and sense is trivially related to a table entry.
In my first "instantiation" (port?), resources are plentiful. I.e., I can use doubles everywhere as space and time are not an issue. So, I can store "sense" as "+1.0" or "-1.0" *in* the tables, etc.
But, I will have to port this to a variety of other processors -- some being severely resource constrained (space *and* time).
Some of these "optimizations" are obvious: e.g., store sense as a signed char and cast it to a double when actually called upon for use (in fact, it is probably *more* logical to treat it as a bivalued *flag* than to assign special values to it -- like +1 and -1).
Other optimizations are a bit more involved -- e.g., using fixed point math in lieu of the doubles, etc.
Still other optimizations are at the whim of the compiler (common subexpression elimination, etc.).
As a rule, I *don't* like trying to outthink the compiler. It leads to more obscure code (which can ultimately lead to BROKEN code as your "organic optimizer" screws up!).
So, I am looking for a nice balance that goes "far enough" to help even poor compilers without unduly obfuscating what the code *wants* to do.
if (sense * (x - y) RELOP 0) { ... }
if ( (sense ? +1 : -1) * (x - y) RELOP 0) ) { ... }
condition = sense ? (x RELOP y) : (y RELOP x) if (condition) { ... }
if (sense) { if (x RELOP y) { ... } } else { if (y RELOP x) { ... } }
etc.
None are particularly appealing :< (note that commentary can clarify the intent of the code fragments; I am more concerned with "maintainers" introducing typographical errors that are harder to catch (e.g., mentioning x and/or y more than once invites a typo in one of those instances to introduce an asymmetrical error that requires additional testing to identify)
I would *really* like to avoid littering the code with #ifdef's designed to tweek it for each particular port :-/
Thx,
--don