I am looking for other ways to write the following in as few lines as
possible, but I think I have hit the limit...
x -= x/abs(x)
So far, I have come up with this(it seems to work anyway):
x -= x > 0 ? 1 : -1
Can anyone see any other way of expressing this as a single expression?
Corvus
Your solutions all have a bug: what if x is zero? Don't optimize until
you've debugged.
It appears that you are trying to calculate the value of the signum
function, which is NOT -1 for zero, nor undefined. Signum is 1 for x >
0, 0 for x==0, -1 for x < 0.
Do it straightforwardly:
x -= x > 0 ? 1 : (x < 0 ? -1 : 0)
A more reliable way would be to package it as a function, and, in the
function, test x for all possible values. In the most general case, x
does not have to be positive, negative or zero: in a weakly typed OO
system it might be a complex number.
x -= signum(x)
float signum(int x)
{
if (x > 0) return 1;
if (x < 0) return -1;
if (x == 0) return 0;
printf("Fatal error, alack the day\n");
}
Of course, in the above, x's being an int guarantees that the last
test is unnecessary, but not in the most general case. For reliability
it never hurts, when classifying something, to explicitly test it for
all possible cases rather than "falling through" to a "default" value;
note that the shift into traditional "programmerese" is a signal that
we're about to revert to barbarism as is also the case when a
programmer starts raving about "buffers": when programmers talk about
"falling through" they mean "I am probably missing something, and
indeed I feel like Alice in the rabbit hole".
I wouldn't use the third test in implementing signum if it can declare
its parameter as one of short, int, long, float or double because in
each case, the runtime, including the famous goddamn stack, guarantees
that x will be zero when not positive or negative...
....except (and this is important, so wake the Christ up) in certain
floating point applications where it might make perfect sense to do
this: I can easily imagine some goddamn scenario where float or double
x is not greater than, less than, or equal to zero, and code inserted
by some slob to catch this when it happens on alternate Tuesdays
during a gibbous moon.
Of course, the fun rilly starts when you implement SIGNUM, a macro: oh
dearie me how did I do that:
#define SIGNUM(x) ((x) > 0 ? 1 : ((x) < 0 ? -1 : 0))
(Ben Bacarisse will probably find ten real bugs in the above macro).
This macro should probably test for all three possibilities since we
have absolutely no idea what x is!
#define SIGNUM(x) ((x) > 0 ? 1 : ((x) < 0 ? -1 : ((x) == 0 ? 0 :
errorHandling())))
There probably are also ways of punning on the representation of
Boolean values as numbers:
#define SIGNUM(x) (x) ? ((x) > 0 ? 1 : -1) : 0
oh gee that saves one jillionth of a terapicosecond.
The best solution? Find a complete math library which defines signum.