Comment On Classic WTF: The Challenges of Negation

It never ceases to amaze me the lengths that certain programmers will go to solve the simplest of problems. Like, say, negation. When "n * (-1)" Won't do ... [expand full text]
« PrevPage 1 | Page 2 | Page 3Next »

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:07 • by mrprogguy
What? n * (-1)?

Most modern languages allow negation simply by prefixing the unary minus symbol to the value.

int a = 1, b = 3;

int c = (-a) * b;

Why go through all the work of an explicit multiplication by negative one? I had to correct one of my developers on that point two weeks ago.

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:11 • by draeath (unregistered)
More examples of what happens when you pay per line.

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:15 • by Vertu (unregistered)
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:33 • by snoofle
-(Nice Code)

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:36 • by Voodoo Coder
236739 in reply to 236733
Vertu:
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.


Seems to me that both of those solutions have the same amount of operations in them as n*(-1)...I can't imagine where n*(-1) would be either less clear, or slower, than any other solutions...but then, maybe I missed the tongue being in the cheek on your comment...

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:37 • by DaveAronson
To be fair, there is at least one case where simply "-n" won't quite work: maximum-magnitude negative integers in two's complement (e.g., "short i = -32768").

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:40 • by Zatanix
236744 in reply to 236731
I think he wrote "n * (-1)" in the article, to make it really explicit that we are talking about negating numbers. If he had written "When '-n' won't do" the meaning would not have been as clear, imo.

(btw, i really doubt that multiplying by -1 is any more work than using unary minus on any modern compiler. Whether it is more readable depends on the situation, but yeah i agree that usually unary minus is prettier)

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:43 • by Yuliy (unregistered)
The second one looks like it takes the long way around taking a bitwise negation within the scope of a byte. The simple way around this is of course "return n ^ 0xFF".

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:48 • by barvins (unregistered)
236748 in reply to 236739
Multiplication is slow. At least on older processors it used to be much slower than subtraction. Of course, it only matters if you are doing processor-intensive stuff like raycasting.

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:49 • by barvins (unregistered)
236749 in reply to 236739
Voodoo Coder:
Vertu:
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.


Seems to me that both of those solutions have the same amount of operations in them as n*(-1)...I can't imagine where n*(-1) would be either less clear, or slower, than any other solutions...but then, maybe I missed the tongue being in the cheek on your comment...


Multiplication is slow. At least on older processors it used to be much slower than subtraction. Of course, it only matters if you are doing processor-intensive stuff like raycasting.
(forgot to quote the stuff I was referring to)

Re: Classic WTF: The Challenges of Negation

2008-12-29 09:53 • by lolwtf
I love the first one. It seems like he even got the basis of it - taking advantage of the fact that an undefined variable starts with a value of zero in VB6 - but didn't quite realize it.

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:12 • by Capt. Obvious (unregistered)
236753 in reply to 236733
Vertu:
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.
Well, keep in mind we're talking about doubles, not shorts/ints/etc. Thus, the first bit is a sign bit. Most efficent would be n^0x8000000000000000 (At least on a 64-bit machine.)

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:13 • by t604 (unregistered)
Um... this smells like bullshit. Someone wrote the code just to submit it.

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:15 • by JamesCurran
236755 in reply to 236745
Yuliy:
The second one looks like it takes the long way around taking a bitwise negation within the scope of a byte. The simple way around this is of course "return n ^ 0xFF".


Actually, the piece at the beginning expanding it to 8 bits will have no effect on the outcome (unless ConvertDecimal requires at least 8 digits) (If strBin is more than 8 characters, the rest will still work).

The size independent method of taking the 1s compliment is "return ~n;"

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:19 • by VibroKatana
236756 in reply to 236749
barvins:

Multiplication is slow. At least on older processors it used to be much slower than subtraction. Of course, it only matters if you are doing processor-intensive stuff like raycasting.
(forgot to quote the stuff I was referring to)


Obviously multiplication will be faster then converting it to a string, doing comparisons and conversions on the like, then parsing it back to a number. With n*-1 (or preferably -n) you should only need 1 pass to get the new value. Shoot the difference between n and -n is usually 1 bit.

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:21 • by JamesCurran
236757 in reply to 236753
Capt. Obvious:
Well, keep in mind we're talking about doubles, not shorts/ints/etc. Thus, the first bit is a sign bit. Most efficent would be n^0x8000000000000000 (At least on a 64-bit machine.)


That assuming that your language/platform allows bitwise operations on floating point numbers (most do not). It also assumes that your cpu uses as it's internal format, the IEEE floating point *exchange* format (not a guarantee).

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:26 • by Code Dependent
Comment * (-1)

(Negative comment)

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:28 • by SpamBot (unregistered)
236759 in reply to 236754
t604:
Um... this smells like bullshit. Someone wrote the code just to submit it.


you must be new here ...

</obligatory>

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:36 • by Code Dependent
Why is poor nDec being ostracized that way? It's not good enough to be on the line with the others?
int c,count,i;
int nDec;

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:41 • by Shriike (unregistered)
Wouldn't the second one not event work?
If I had 0 (00000000) it would return -1 (11111111)
so obviously he wasn't as stupid as we thought, he wasn't trying to just reverse the sign of a number, he was reversing the sign and then taking -1

Captcha: opto (I enjoyed it)

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:43 • by Brillant Mathman (unregistered)
Everyone knows the best and proper way to negate a number is

n = n - 2*n;

Nice and clear.

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:44 • by Bernie (unregistered)
236763 in reply to 236754
t604:
Um... this smells like bullshit. Someone wrote the code just to submit it.

Your comment smells like BS. I think you wrote it just to submit... errr... nevermind. Now that my brain is awake, I'd like to introduce the amazingly stupid recursive comment: this comment!

Re: Classic WTF: The Challenges of Negation

2008-12-29 10:48 • by Bob Dole (unregistered)
The real WTF is VB6.(Did I do that right?) In VB6, you can't return a value so you have to set the function equal to the value before exiting the function. I hate that BS "Function = Value" syntax. Functions aren't variables, cut that shit out.

\You may hate on VB, but VB .Net made it so you can return, and you don't have the OnError logic crap. VB6 may be the devil. You can hate on VB, but VB6 is the real issue.

Re: Classic WTF: The Challenges of Negation

2008-12-29 11:06 • by Kris (unregistered)
236771 in reply to 236754
t604:
Um... this smells like bullshit. Someone wrote the code just to submit it.


I'm guessing one of the above posters got it right. Whoever wrote that is being paid by the line.

Re: Classic WTF: The Challenges of Negation

2008-12-29 11:19 • by iToad (unregistered)
i = (i ^ 0xFFFFFFFF) + 1;

Assuming:
- All integers are 32 bits.
- Two's complement integer storage.
- Programming in C.
- Error checking is for wimps.

Re: Classic WTF: The Challenges of Negation

2008-12-29 11:21 • by CrazyBomber
236775 in reply to 236731
Here's a neat code obfuscation technique:

int i = 24742;
int negative = 2323234;

negative =- i;



Or is it too easy to spot? :)

Re: Classic WTF: The Challenges of Negation

2008-12-29 11:39 • by DWalker59
236777 in reply to 236756
VibroKatana:
Shoot the difference between n and -n is usually 1 bit.


Shoot, it's not 1 bit, at least not in two's complement form. You'll find that ALL of the bits are flipped, and the sign bit is 1 instead of 0. I think.

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:10 • by sf (unregistered)
236783 in reply to 236733
Vertu:
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.

Well for one thing negation usually means change of sign, so 0-n would not work unless you knew n was always positive. -1 * n will always work. You are correct about -n, though, if your language supports it. Not all do.

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:11 • by Crash Magnet (unregistered)
236785 in reply to 236777
DWalker59:
VibroKatana:
Shoot the difference between n and -n is usually 1 bit.


Shoot, it's not 1 bit, at least not in two's complement form. You'll find that ALL of the bits are flipped, and the sign bit is 1 instead of 0. I think.


n = (~n) + 1;

Clear, n'est pas

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:28 • by Dave (unregistered)
236787 in reply to 236783
sf:
Vertu:
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.

Well for one thing negation usually means change of sign, so 0-n would not work unless you knew n was always positive. -1 * n will always work. You are correct about -n, though, if your language supports it. Not all do.


0 - -1 = 1, sign changed.
0 - 1 = -1, sign changed.

where's the problem?

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:30 • by Dave (unregistered)
236788 in reply to 236787
Dave:
sf:
Vertu:
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.

Well for one thing negation usually means change of sign, so 0-n would not work unless you knew n was always positive. -1 * n will always work. You are correct about -n, though, if your language supports it. Not all do.


0 - -1 = 1, sign changed.
0 - 1 = -1, sign changed.

where's the problem?


In addition, 0 - n is faster for floating point than -1 * n is, in many cases...(premature optimization my ass)

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:35 • by Mitur Binesderti (unregistered)
You guys are so negative...

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:40 • by campkev
236791 in reply to 236783
sf:

Well for one thing negation usually means change of sign, so 0-n would not work unless you knew n was always positive.


Oh lord, please tell me you are joking.
If you aren't, please tell me you are looking for a different line of work or at least are not anywhere near any code I am going to have to maintain in the future.

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:49 • by Fabien (unregistered)
What a great language, it seems that "dblTempValue" is initialized by default with zero. And the author makes sure to make "dblTempValue - dblMagnitude" to confuse the reader

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:51 • by Kuba
236796 in reply to 236783
sf:
Vertu:
Why n*(-1), I think 0-n or simply -n would usually be faster and better operation.

Well for one thing negation usually means change of sign, so 0-n would not work unless you knew n was always positive.


I hope it was just a brainfart.

0-(-5) = 0+5 = 5
0-(5) = -5

See it now?

Re: Classic WTF: The Challenges of Negation

2008-12-29 12:57 • by Kuba
236797 in reply to 236788
Dave:
Dave:
0 - -1 = 1, sign changed.
0 - 1 = -1, sign changed.

where's the problem?
In addition, 0 - n is faster for floating point than -1 * n is, in many cases...(premature optimization my ass)
Any reasonable compiler will reduce 0-n and (-1)*n and -n to a single-opcode floating point negation; with associated load/store *iff* the value is not in a FP register at given point.

I have seen a cleverest compiler a while ago, which "knew" that a load/negate/store was slower on a particular architecture than handling it using integer mask and complement instructions. So, if the value couldn't be made to be in FP register (the compiler did instruction reordering), it'd relent and do it using integer opcodes. The difference was small (IIRC 2 clock cycles).

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:02 • by lesle (unregistered)
236798 in reply to 236748
Well, multiplication is slower because it's actually repetitive addition, or at least it was 35 years ago on big iron. Likewise, division is repetitive substraction.

Has that really changed?

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:14 • by clickey McClicker (unregistered)
So does 0*-1 = -0 or just plain 0.



Re: Classic WTF: The Challenges of Negation

2008-12-29 13:31 • by Franz Kafka (unregistered)
236803 in reply to 236801
clickey McClicker:
So does 0*-1 = -0 or just plain 0.



Depends on the language. Some allow for a -0 that is !=0, while I think others use it as an init value that can be tested but is never produced by arithmetic.

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:40 • by Brad (unregistered)
If I had to guess, I'd say that code was somebody's homework in a programming class.

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:44 • by KenW
236806 in reply to 236754
t604:
Um... this smells like bullshit. Someone wrote the code just to submit it.


Ummm... this smells like bullshit. Someone wrote this comment just to say something.

You must be new here. Go back and review other archived posts here. You'll see plenty of examples as bad as these (and some a lot worse).

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:44 • by Duke of New York (unregistered)
236807 in reply to 236754
t604:
Um... this smells like bullshit. Someone wrote the code just to submit it.

It seems reasonable to assume that you've never worked with outsourced code.

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:53 • by mbessey
236808 in reply to 236798
lesle:
Well, multiplication is slower because it's actually repetitive addition, or at least it was 35 years ago on big iron. Likewise, division is repetitive subtraction.
Has that really changed?


Yes, it really has. Multiplication and division are fixed time, single cycle operations on most CPUs now (really, since about 1990 or so). Unless you're programming an 8-bit microcontroller, it's nearly always faster to do things the obvious way, rather than the "clever" way.

On a pipelined, superscalar CPU (i.e. most desktop/server systems), load & store time and cache behavior have much more effect on performance than using multiply vs bit-shifting, for example.

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:55 • by ciph3r (unregistered)
You're all wrong! *shakes head*
over-complicating! *mumbles to self*

dblVal = val * 2;
for(int i=0;i<dblVal;i++)
val--;

THERE!

Re: Classic WTF: The Challenges of Negation

2008-12-29 13:58 • by Mcoder
236810 in reply to 236740
DaveAronson:
To be fair, there is at least one case where simply "-n" won't quite work: maximum-magnitude negative integers in two's complement (e.g., "short i = -32768").


No other alternative will work here either, mainly because it can't be done. Now, "-n" will create an overflow error, that your program will ignore anyway, since you are not coding in assembly.

Also, for the others, there is no speed difference on integer addition and multiplication on consumer-grade hardware since the 486, there is no difference for floating point for a wile either. Also, about floating point, most compilers will turn "-n" into a bit flipping anyway, it will probably also work for "0 - n" and "-1 * n", altough it simply can't deal with very "smart" constructions.

Re: Classic WTF: The Challenges of Negation

2008-12-29 14:29 • by Shmork (unregistered)
First rule of programming: no matter how WTF a piece of code is, there will always be someone to defend it.

Re: Classic WTF: The Challenges of Negation

2008-12-29 14:43 • by harry (unregistered)
236815 in reply to 236783
sf:
Well for one thing negation usually means change of sign, so 0-n would not work unless you knew n was always positive.
Since people complained about this:
$ cat negzero.c

#include <stdio.h>
int main(void) {
printf("%g\n", 0 - 0.);
printf("%g\n", -1 * 0.);
return 0;
}
$ c89 negzero.c -o negzero
$ ./negzero
0
-0

Re: Classic WTF: The Challenges of Negation

2008-12-29 14:45 • by Steve H. (unregistered)
236816 in reply to 236810
Mcoder:
Also, for the others, there is no speed difference on integer addition and multiplication on consumer-grade hardware since the 486

Not if you program on small embedded processors that don't have a multiply instruction (or take much longer to multiply than divide).

Re: Classic WTF: The Challenges of Negation

2008-12-29 14:48 • by Dirk Diggler (unregistered)
236817 in reply to 236813
Shmork:
First rule of programming: no matter how WTF a piece of code is, there will always be someone to defend it.
I thought we weren't supposed to talk about it.

Re: Classic WTF: The Challenges of Negation

2008-12-29 15:30 • by hcs (unregistered)
236818 in reply to 236815
for what little it may be worth:

$ cat negzero.c
#include <stdio.h>
int main(void) {
double i = 0 - 0.;
double j = -1 * 0.;
printf("%g\n", i );
printf("%g\n", j );
if ( i == j ) printf("i == j\n");
if ( i == 0 ) printf("i == 0\n");
if ( i == 0. ) printf("i == 0.\n");
if ( j == 0 ) printf("j == 0\n");
if ( j == 0. ) printf("j == 0.\n");
if ( i < 0 ) printf("i < 0\n");
if ( i < 0. ) printf("i < 0.\n");
if ( j < 0 ) printf("j < 0\n");
if ( j < 0. ) printf("j < 0.\n");
return 0;
}
$ c89 negzero.c -o negzero
$ ./negzero
0
-0
i == j
i == 0
i == 0.
j == 0
j == 0.

Some of the comparisons are redundant as the 0 is promoted to 0. anyway. I don't know what how much of this is processor-dependent, compiler-dependent, or specified by the C standard.
And this is why I hate floating point. (also boo for bonus newlines)
« PrevPage 1 | Page 2 | Page 3Next »

Add Comment