- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Two points:
Why do you think it makes a difference whether
x
is positive, negative, or even zero?Why do people feel compelled to write
x * -1
as a way to negatex
, instead of-x
?Admin
re #2: I have seen this so many times before too and came to the conclusion: people don't know any better. It's sad.
Admin
#1) it is said in the context of explaining how this construct would work to produce an absolute value.
#2) they both compile to a single NEG opcode so it doesn’t matter.
Admin
This fundamental misunderstanding of the simplest, most basic math is the real WTF. Sorry Kendall, please find another career. There is no excuse for this code. The "typo" I can understand. All the rest of it...
If people think I'm too harsh: My predecessor had about the same level of math stills. Didn't even understand negative values, yet still wrote control loops for the temperature of overheated steam. It's plain scary.
Addendum 2024-08-21 08:25: overheated = superheated
Admin
The line between underthinking and overthinking is thin, and some people are playing hopscotch with it without even knowing it.
Admin
That code was not written by Kendall.
It was written by
0.0 - Kendall
Admin
short abs(short x) { short mask = x >> (sizeof(short) * 8 - 1); return (x + mask) ^ mask; }
Admin
Are there really still languages out there where you need to reinvent abs()? If that's indeed what's attempted here...
Admin
You could be right - maybe Kendall doesn't understand math and needs to find another career. At the same time this code could have been written at 3am after working all day because the boss had made a promise to a customer!
Admin
If the compiler is intelligent enough to do that optimisation
If the architecture has a
NEG
opcode.Admin
Because, of course, you've never written code that stupid in your career, not even when you were really tired or under great pressure.
Admin
If people only did the things they need to, this site would be pretty boring. Much more interesting when you don't need to do something, but you come up with a "creative" way of doing it anyway.
But in this case, it's not just about the abs, as evidenced by the other line there. I've seen code like this before, looks like resizing a box in a UI: left side is out of bounds, so move it in bounds and decrease the width to keep the right side in the same place.
Admin
No. Not to that extent. Yes, I've done some stupid stuff, howlers even, and costly ones at that. But I have never, ever substracted a value from zero, just to simulate a negation. If you're that clueless of the mathematical tools at your disposal, then get the out of the kitchen before someone gets burned. This is not a sleep-deprived brain-fart, it is far worse and deeply unsettling.
To me, that's on the level of an obstacle runner not knowing how to properly ties the shoelaces.
Admin
The fact that width is also adjusted leaves me with a little bit of doubt that the purpose was to make x a positive number. If x is a coordinate and width is... width, this code will move whatever is placed outside the normal bounds of a window to inside the window, and reduce the width so the right edge is in the same spot. Of course, that could have been achieved with simply x = 0 and the same width adjustment, so there's that, but x = 0 wouldn't be very symmetrical with the change to width, so my best guess would be that the calculation 0.0 - x came first, and the x += and width -= came after.
Admin
Are we really going to ignore the width variable when assuming this was intended to do just an abs?
The operation we are seeing here is
Equivalent to
if the language allows it.
We can't even for sure say what the bug was, considering the presence of "width" inside the conditional block.
Admin
In addition to what @jeremypnet said, it does matter, for a reason that falls into the "90%" side of the 90%/10% split of a programmer's job.
The 10% side is all that programming junk, designing stuff, writing code and all that. The 90% side is "communicating with other humans", and if you write code in a slightly weird way, you're communicating "my code does this in a weird way for some weird reason", and you're not communicating the reason. (Audience of this communication: your fellow programmers, including yourself in six months or a dozen years)
-x
is the "non-weird" way to write negation, so nobody much will look twice other than to verify that negation is really needed.0 - x
andx * -1
(and even-1 * x
) are weird ways to write it, and I'm likely to spend time wondering what's so special about it that it can't be just written as-x
, going even so far as to see if there are weird things like inconsistencies between your overloadedoperator -(const MyThing&)
,operator -(double, const MyThing&)
andMyThing::operator *(double)
.That's why it matters.
Admin
I suspect they conceptualize
-
as a negative sign on number literals, not as a unary operator. So you can write-3
, but not-x
. Even if they know this intellectually, it's not intuitive to them, so they findx * -1
a better way to express their intent.Any compiler that doesn't produce the same code for both (assuming no operator overloading that actually makes them different, which would be a WTF itself) is not worth considering.
Admin
There is an issue with this code nobody here seem to have spotted. If this is C/C++ or C#, heck even JavaScript, x is literally cast to float by
0.0 - x
. Now for C variants this is really bad, because double operations are better performing, in fact C# only does double operations, the float will be converted back to a double before the subtraction. Granted, Roslyn now does this literal conversion in most cases automatically, but boy, this is a bigger code smell than anything else in this snippet IMO.BTW the correct way to 2s-complement a number in C syntax languages is x = -x; for those interested 1s-complement is x = ~x. x *= -1 would be equally a bad style because now you are at the mercy of the compiler to optimize that to a 2s-complement operation.
Admin
NEG predates IMUL immediate on x86 architectures, and far from it requiring a compiler “intelligent” enough to optimise, I suspect there has never been a compiler that would select the longer (in both space and time dimensions) IMUL immediate over NEG unless explicitly forced to.
Admin
If you’re this shook by the concept of multiplying a number by negative one that your productivity would immediately grind to a halt, then I think you might be in the wrong career?
Admin
I have to say, kudos to Kendall for publishing their own WTF. That shows courage, an honest unflinching self-awareness, and a strong desire to improve.
Admin
Hello Rick.
Sorry to say this but that is a bigger WTF than the original code. It is obscure, buggy and adds nothing except fixed execution time.
A better abs would be: short abs(short x) { return (x<0) ? -x : x; } or even make it a macro so it would work inline and with any type.
It could be changed to:
short abs(short x) { short mask = x >> (sizeof(short) * 8 - 1); return (x ^ -mask) + mask; } // If the high bit is set exor by -1 and add 1, otherwise do nothing.
Although I would still say that was a WTF. The only time I know that fixed execution time is required is in a security system and none (as far as I know) require abs.
Sorry to be so pedantic.
Admin
For some reason I'm never sure whether -x will work, especially if x is already negative, even though I'm pretty sure it will work in most languages.
Admin
Nope. 0.0 is double in C and C++. 0.0f would be float. https://en.cppreference.com/w/cpp/language/floating_literal
Admin
And even if 0.0 was a float literal, an operation between float and double (assuming x is double) would cast both arguments to double. In no case would x be cast to float for the subtraction.
Admin
Yeah, that's a good point, because they totally never saw
-x
in any mathematics lesson. Never, not once.Here endeth (for the moment) the sarcasm.
Admin
Sometimes microsecond is eternity. Usually not. So everything depends on the context where the code is run. Old timers tend to think about these things even tough it is no more necessary.
Admin
Because the intention of the code is much easier to spot while casually scrolling through. It's the same as writing if (x == true) vs if(x) or adding explicit braces and spacing even for a single clause if.
Admin
Hi LZ79LRU:
Don't do comparasions on booleans. if(x) and if(x==true) are not the same thing. if(x) evaluates as true if x is non zero if(x==true) only evaluates as true if x is 1 (for most languages, but not all.)
Ugly as it is, there are reasons why people do things like if(!!x==!!y), becauses it forces the evaluation of each boolean variable, rather than doing a comparasion.
Admin
Most practical architectures do; it's really easy to implement in the ALU if you already have a SUB opcode.