The uncertainty that enters the picture when comparing two quantities whose difference is close to the limit of the double's representation still applies to this implementation; all the coder has done is to convert to a different representation of the number; that doesn't help any!

The uncertainty itself is semantic; it's the difference between what you wanted to store in the number, and what actually got stored - no matter how you look at the stored number, the uncertainty doesn't change.

Ken Arnold wrote this in August 1989 Unix Review and I quote:

"It is a little known fact that despite the commonality of two's-complement machines, there is some disagreement about the representation of some numbers. For example, on a two's complement machine, the representation of -1 is (in 8 bits) is 11111111, whereas in a one's complement machine it would be 10000001.

Generally speaking, you cannot rely upon the underlying representation of even integers...

Portability can be enhanced, therefore, if you don't use literal integers in your expressions, but use the conversion routines for symbolic names to prevent any mixup with the representation. For example, instead of the common i++; you should really say

i += atoi("1");.

If you pass in a string version of the number you want, the atoi() routine knows how to decode it into the true representation for the current machine. Similarly, for relative comparisons, you should say,

What language was this written in? It's kind of hard to tell when a "C"-like code snippet is posted. It almost looks like C#, except the line "string nStr = n.ToString" isn't valid C# code (missing the () after ToString), and the nStr variable is referenced as nstr (note the lowercase "s").

It looks to me at a glance that it's only searching the first character for the negative sign too. If I'm not mistaken, the "negative symbol" appears to the right of the digits in some cultures. What these cultures are, well, I have no clue.

You can't denie this little function really enhances readability like in:

if (IsNegative(velocity))
{
throw new InvalidOperationException("Dude!... You are moving backwards!");
}

However I have a problem with the posted implementation as some already said, it could lead to i18n issues, besides... Why would someone transform that double to a string? I'm not talking about performance here ‘cause knowing that a value is negative is truly important so if it takes some time to know it IMHO all that time is worth it, I'm talking about something more important. As soon as non programmers see his code they going to believe programming it's easy, what wee need here is keep the algorithm in the mathematic domain. We don't need this people to come to our world. It's hard already with all that IT outsourcing going on. So what do you think about the following little refactoring?

By the way -- what if n is something like .00000000001?

I believe the ToString method will generate something in the form of "1.0E-17" -- which this method would interpret as being a negative number since it contains a "-" symbol at any position.

@JeffS
The function as it is would not return true for 1.0E-17 as it search for the little - at the first position.

BTW, that's makes me see this function shouldn't compile in C# as there isn't an implicit conversion form int to bool in C# (IndexOf does return an int), so now I really doubt this is C# at all... maybe JScript.Net or something like that.

Both mrd and chandler raised an important question.

I presume that C# implements IEEE 754 numbers, and therefore has both 0.0 and -0.0. An interesting property is that 0.0 == -0.0.

The only way I know of telling the two apart, short of looking at the textual representation or bit pattern, is by checking the sign of 1/x (1/0.0 is infinity, 1/-0.0 is negative infinity.)

I don't think this can be .NET .... because the answer would be reversed !

The IndexOf method in a string returns the position of the match if there is one (starting at ZERO for the first position in the string), or -1 if there is no match.

So the expression returns 0 if there is a
"-" in the first position, or -1 if there is not !

And if -1 is returned by the expression, this function returns TRUE indicating that the number is negative!

(Am I missing something here?)

Wouldn't this cause the function to always return the OPPOSITE value of what it should?

if n is negative infinity, n < 0 will return true but the method above returns false. So if the intent of the function is to return true for ordinary negative numbers but not for negative infinity then its not a WTF, just a badly named function....

This has got to be my new all-time favorite blog...

Yeah... this seems to be more complicated of what I initially thought... there are too many questions, like:
Is this C#? (I strongly doubt)
Does this function returns true when n <0? (Now it seems that it's just the opposite)
Does –0 < +0? (my brains hurts by now)...
I think I just walk away and get some fresh air.

LOL @Wojo implementations, but joking aside you need to cast to decimal on some of your functions there and take care of those pesky OverflowExceptions that may happen.

@ Alex Papadimoulis, I think you should revert the changes in the code as it's pretty obvious this is not C#.

@Wojo...
damn it! disregard what I said of your code. I thought to remember Abs always returned a decimal when in fact does return a value of the type of the parameter.
So yes... your code rocks man. ;-)

Guayo, no worries. I didn't try to even compile any of that, much less test it, so it wouldn't surprise me if there were bugs. :-)

I actually caught one after posting. In the 3rd function, I think it should be Math.Floor instead of Math.Ceiling, since I think declaring an array of size 0 is legal in C#?

I'm sad to say that I've worked with a fellow developer that asked me how to tell if a number is negative. It took me a while to answer because I was flabergasted. When I answered less then zero. The wheels spun in their head and they thanked me. It wasn't until 5 minutes latter that they walked back and told me that it was a dumb question.
It's still better then the guy that couldn't figure out array indexing. All the table rows he output all had the same value. He couldn't grasp that arrays didn't increment like recordsets.

This is a crap! If the regional settings are different, negative numbers may be represented by parentheses, like (30). To avoid these conflicts, i suggest checking the sign of n*n, and if there is NO sign, n is negative.
LOL, WTF :]

We all know that there are numbers that are positive, and some of them are negative. Sometimes a number is neither negative or positive. We have to sort these cases out! We should implement IsNegative in Pascal as follows:

function IsNegative( n : double) : boolean;
begin
// i've revised your code, Steve, and i think
// you should use IF here!
Result := FloatToStr( nn)[ 1] in ['0','1','2','3','4','5','6','7','8','9']
end;

function IsPositive( n : double) : boolean;
begin
Result := not( FloatToStr( nn)[ 1] in ['0','1','2','3','4','5','6','7','8','9'])
end;

function IsNegativeForReal( n : double) : boolean;
begin
Result := IsNegative( n) and (not IsPositive( n));
end;

function IsPositiveForReal( n : double) : boolean;
begin
Result := (not IsNegative( n)) and IsPositive( n);
end;

function IsNegativeFinal2( n : double) : boolean;
begin
// this will work very stable
Result := IsNegativeForReal( n) and (not IsPositiveForReal( n));
end;

Hey, what's wrong with just doing a switch/select on all possible numbers? Since (I don't think) C# has this functionality, here it is in VB...

Function IsNegative(n as double) as boolean
Select Case n
Case 0,0.000000000000001, 0.000000000000002, ...
Return false
Case -0.000000000000001, -0.000000000000002...
Return true
Case Else
Return "WTF?".ToBoolean()
End Select
End Function

should always return false, since the results of both sides will be NaNs, and NaNs never compare equal. Or perhaps this language actually break that rule?

That's not a language that I'm familiar with (I didn't notice anyone identifying it above), but I do know that the hapless owner of this site has shown his ignorance again.

Here's some Java that expresses why in many languages "(n<0) won't do":

public class Foo {
public static void main(String... args) {
double d = -0d;
// Displays "false", NOT "true".
System.out.println(d < 0d);
}
}

Negative Zero is a legitimate quantity in many languages. Java is one of them. Possibly the one the quoted author uses is one of them.

That said... it's still an iffy implementation.

To the site owner: Please TELL US what language any given WTF is in. If you don't know, don't post it, because how the fuck are you supposed to know it's stupid if you don't know anything about the language?

The listed code seems to be C# because it uses IndexOf note the uppercase of the I and the O.
The ECMA-334 C# Language Specification requires the support of negative zero for doubles. <a href=http://www.jaggersoft.com/csharp_standard/11.1.5.htm>reference here</a>

@Dave M.
I didn’t get why are you being rude here. That implementation it’s stupid no matter what the language is, I think it was a great WTF. Knowing the language would be better and in some occasions it would be mandatory to know the language to see if a piece of code its WTF or not, this is not the case.

Comment far above about velocity. Velocity is a vector quantity and can be negative. Speed is a scalar and cannot.

The only way I can think of that would make sense of this would be for fractions or some other strange numeric system that is treated as strings. Ex. If you wanted to store 1.5 as "1 1/2" what's written would be a better way of determining a negative number than doing the lookup to find the numeric value and arithmetic.

actually i once managed to trick the basic interpreter on my commodore 64 to geneate -0 as result of some operation - which is case where this routing might be useful

If you really want to include -0 as a negative number (even though it's mathematically nonsensical), just do something like:

if (num < 0.0 || num == -0.0)

That assumes that 0 != -0.0 and makes no other assumptions about the various possible combinations of stupid comparisons between stupid non-numbers which only exist "because they can."

Admin

Wow.

I know the inevitable commentary will spring up about how the number is a double and might suffer from imprecision in comparisons.

--but that still doesn't justify

this.Wow.

Admin

And people question the fact that good programmers can easily outperform the bad ones by a factor of 5

Admin

The uncertainty that enters the picture when comparing two quantities whose difference is close to the limit of the double's representation still applies to this implementation; all the coder has done is to convert to a different representation of the number; that doesn't help any!

The uncertainty itself is semantic; it's the difference between what you wanted to store in the number, and what actually got stored - no matter how you look at the stored number, the uncertainty doesn't change.

Admin

Ken Arnold wrote this in August 1989 Unix Review and I quote:

"It is a little known fact that despite the commonality of two's-complement machines, there is some disagreement about the representation of some numbers. For example, on a two's complement machine, the representation of -1 is (in 8 bits) is 11111111, whereas in a one's complement machine it would be 10000001.

Generally speaking, you cannot rely upon the underlying representation of even integers...

Portability can be enhanced, therefore, if you don't use literal integers in your expressions, but use the conversion routines for symbolic names to prevent any mixup with the representation. For example, instead of the common i++; you should really say

i += atoi("1");.

If you pass in a string version of the number you want, the atoi() routine knows how to decode it into the true representation for the current machine. Similarly, for relative comparisons, you should say,

if (count < atoi("10"))

This mechanism gives you maximum portability..."

:)

Admin

What language was this written in? It's kind of hard to tell when a "C"-like code snippet is posted. It almost looks like C#, except the line "string nStr = n.ToString" isn't valid C# code (missing the () after ToString), and the nStr variable is referenced as nstr (note the lowercase "s").

Admin

Is -0.0 less than 0.0?

Admin

I would guess it's badly transcribed C#.

Admin

It's a strange error that occurs in the Screenshot->Text routine I use. It would seem that there are occasional typos.

:-D

Admin

It looks to me at a glance that it's only searching the first character for the negative sign too. If I'm not mistaken, the "negative symbol" appears to the right of the digits in some cultures. What these cultures are, well, I have no clue.

Admin

No idea what language this code is.

If it's legitimate, wow.

Admin

Looks like the transcribed code ahas been fixed .. It's bad C# now.

Admin

while(nstr != nStr)

{

//noop

}

Admin

how about this instead :p

bool IsNegative(double n)

{

string nStr = n.ToString();

double index = nStr.IndexOf('-');

return !IsNegative(index);

}

now that would be a mongo wtf

Admin

Does Java have -0.0? If so, what is the result of comparing that via d < 0?

Admin

You can't denie this little function really enhances readability like in:

if (IsNegative(velocity))

{

throw new InvalidOperationException("Dude!... You are moving backwards!");

}

However I have a problem with the posted implementation as some already said, it could lead to i18n issues, besides... Why would someone transform that double to a string? I'm not talking about performance here ‘cause knowing that a value is negative is truly important so if it takes some time to know it IMHO all that time is worth it, I'm talking about something more important. As soon as non programmers see his code they going to believe programming it's easy, what wee need here is keep the algorithm in the mathematic domain. We don't need this people to come to our world. It's hard already with all that IT outsourcing going on. So what do you think about the following little refactoring?

bool IsNegative(double n)

{

return n * double.PositiveInfinity == double.NegativeInfinity;

}

Admin

A definite WTF.

By the way -- what if n is something like .00000000001?

I believe the ToString method will generate something in the form of "1.0E-17" -- which this method would interpret as being a negative number since it contains a "-" symbol at any position.

Admin

@JeffS

The function as it is would not return true for 1.0E-17 as it search for the little - at the first position.

BTW, that's makes me see this function shouldn't compile in C# as there isn't an implicit conversion form int to bool in C# (IndexOf does return an int), so now I really doubt this is C# at all... maybe JScript.Net or something like that.

Admin

Both mrd and chandler raised an important question.

I presume that C# implements IEEE 754 numbers, and therefore has both 0.0 and -0.0. An interesting property is that 0.0 == -0.0.

The only way I know of telling the two apart, short of looking at the textual representation or bit pattern, is by checking the sign of 1/x (1/0.0 is infinity, 1/-0.0 is negative infinity.)

Admin

I don't think this can be .NET .... because the answer would be reversed !

The IndexOf method in a string returns the position of the match if there is one (starting at ZERO for the first position in the string), or -1 if there is no match.

So the expression returns 0 if there is a

"-" in the first position, or -1 if there is not !

And if -1 is returned by the expression, this function returns TRUE indicating that the number is negative!

(Am I missing something here?)

Wouldn't this cause the function to always return the OPPOSITE value of what it should?

Admin

Aha! I found out why n < 0 won't do...

if n is negative infinity, n < 0 will return true but the method above returns false. So if the intent of the function is to return true for ordinary negative numbers but not for negative infinity then its not a WTF, just a badly named function....

This has got to be my new all-time favorite blog...

Admin

Yeah... this seems to be more complicated of what I initially thought... there are too many questions, like:

Is this C#? (I strongly doubt)

Does this function returns true when n <0? (Now it seems that it's just the opposite)

Does –0 < +0? (my brains hurts by now)...

I think I just walk away and get some fresh air.

Admin

But there are so many better ways to implement the method.

Let's see... (using C# here)

bool IsNegative(double d)

{

return (Math.Abs(d) != d);

}

bool IsNegative(double d)

{

return (Double.IsNaN(Math.Sqrt(d)));

}

bool IsNegative(double d)

{

int n = Math.Ceiling(d);

try

{

Object[] o = new Object[n];

}

catch (ArgumentOutOfRangeException e)

{

return true;

}

return false;

}

...What? Am I missing something? :-)

Admin

LOL @Wojo implementations, but joking aside you need to cast to decimal on some of your functions there and take care of those pesky OverflowExceptions that may happen.

@ Alex Papadimoulis, I think you should revert the changes in the code as it's pretty obvious this is not C#.

Admin

@Wojo...

damn it! disregard what I said of your code. I thought to remember Abs always returned a decimal when in fact does return a value of the type of the parameter.

So yes... your code rocks man. ;-)

Admin

Guayo, no worries. I didn't try to even compile any of that, much less test it, so it wouldn't surprise me if there were bugs. :-)

I actually caught one after posting. In the 3rd function, I think it should be Math.Floor instead of Math.Ceiling, since I think declaring an array of size 0 is legal in C#?

Admin

Assuming this is C#, why not just use the Sign function in the Math class???

Admin

FYI : [ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemmathmemberstopic.asp ]

Admin

I'm sad to say that I've worked with a fellow developer that asked me how to tell if a number is negative. It took me a while to answer because I was flabergasted. When I answered less then zero. The wheels spun in their head and they thanked me. It wasn't until 5 minutes latter that they walked back and told me that it was a dumb question.

It's still better then the guy that couldn't figure out array indexing. All the table rows he output all had the same value. He couldn't grasp that arrays didn't increment like recordsets.

Admin

//return whether a double is less than Pi

bool IsLessThanPi(double n)

{

return IsNegative(n - 3.1415926);

}

Admin

This is a crap! If the regional settings are different, negative numbers may be represented by parentheses, like (30). To avoid these conflicts, i suggest checking the sign of n*n, and if there is NO sign, n is negative.

LOL, WTF :]

Admin

Solution B.

We all know that there are numbers that are positive, and some of them are negative. Sometimes a number is neither negative or positive. We have to sort these cases out! We should implement IsNegative in Pascal as follows:

function IsNegative( n : double) : boolean;

begin

// i've revised your code, Steve, and i think

// you should use IF here!

Result := FloatToStr( n

n)[ 1] in ['0','1','2','3','4','5','6','7','8','9']

n)[ 1] in ['0','1','2','3','4','5','6','7','8','9'])end;

function IsPositive( n : double) : boolean;

begin

Result := not( FloatToStr( n

end;

function IsNegativeForReal( n : double) : boolean;

begin

Result := IsNegative( n) and (not IsPositive( n));

end;

function IsPositiveForReal( n : double) : boolean;

begin

Result := (not IsNegative( n)) and IsPositive( n);

end;

function IsNegativeFinal2( n : double) : boolean;

begin

// this will work very stable

Result := IsNegativeForReal( n) and (not IsPositiveForReal( n));

end;

Admin

I forgot to use CASE! Steve will punish me! ;))))

Admin

Back in the days, when you steel something your hand was removed for this terrible crime. In this case let's just stick to the fingers...

Admin

Zka: You do of course realise that N*N is ALWAYS POSITIVE.... (assuming N is a number and not NaN).

?

Admin

Hey, what's wrong with just doing a switch/select on all possible numbers? Since (I don't think) C# has this functionality, here it is in VB...

Function IsNegative(n as double) as boolean

Select Case n

Case 0,0.000000000000001, 0.000000000000002, ...

Return false

Case -0.000000000000001, -0.000000000000002...

Return true

Case Else

Return "WTF?".ToBoolean()

End Select

End Function

Admin

Ray, just use one case for every possible number. =D

Andy, maybe he worked in a language like PHP, where $array[] will add a new value (based on the largest current numberic key).

Admin

OOo, sneaky.

I notice you're not putting all the values in order - there's an infinite number of values missing just between the first two you list.

(OK, so not really infinite, since no computer can deal with all real numbers.)

BTW, Guayo, your function

bool IsNegative(double n)

{

return n * double.PositiveInfinity == double.NegativeInfinity;

}

should always return false, since the results of both sides will be NaNs, and NaNs never compare equal. Or perhaps this language actually break that rule?

Nice idea, though.

Admin

Sam: i do :) But i tried to create a more f*cked-up version :)

Admin

I am speechless...

Normally I would try to come up with a more f'ed up version of the code, but (and I respect the previous submissions) it isn't possible.

Admin

That's not a language that I'm familiar with (I didn't notice anyone identifying it above), but I do know that the hapless owner of this site has shown his ignorance again.

Here's some Java that expresses why in many languages "(n<0) won't do":

public class Foo {

public static void main(String... args) {

double d = -0d;

// Displays "false", NOT "true".

System.out.println(d < 0d);

}

}

Negative Zero is a legitimate quantity in many languages. Java is one of them. Possibly the one the quoted author uses is one of them.

That said... it's still an iffy implementation.

To the site owner: Please TELL US what language any given WTF is in. If you don't know, don't post it, because how the fuck are you supposed to know it's stupid if you don't know anything about the language?

Admin

Whoa, it wasn't until Comment #40 that someone justified this. I see some people just aren't on the ball ;-)

Admin

The listed code seems to be C# because it uses IndexOf note the uppercase of the I and the O.

The ECMA-334 C# Language Specification requires the support of negative zero for doubles. <a href=http://www.jaggersoft.com/csharp_standard/11.1.5.htm>reference here</a>

Admin

@Alan Bellingham

AFAIK...

NegativeInfinity != NaN

sqrt(-1) == NaN

1/0 == PositiveInfinity

-1/0 == NegativeInfinity

NegativeInfinity < MinValue < MaxValue < PositiveInfinity

Admin

@nobody

It's not C# because nstr.IndexOf('-', 0, 1)) does not returns a boolean value... it could be JScript.Net

Admin

@Dave M.

I didn’t get why are you being rude here. That implementation it’s stupid no matter what the language is, I think it was a great WTF. Knowing the language would be better and in some occasions it would be mandatory to know the language to see if a piece of code its WTF or not, this is not the case.

BTW. I’m sure now this is not JScript.Net

Admin

This is C#. I just went back and looked at the original email.

When typing out the screenshot, I also neglected to do "==0". As if you can't tell from the spelling and grammar, I'm not a detail guy.

Next time I'll just keep the screenshot. It's sad I get two typos in like 3 lines of code ;-).

Admin

So that explains it. The "==0" is critical to this function, as it is written!

Because as I mentioned, without the "==0", the function returns the OPPOSITE of what it says it does.

Admin

Comment far above about velocity. Velocity is a vector quantity and can be negative. Speed is a scalar and cannot.

The only way I can think of that would make sense of this would be for fractions or some other strange numeric system that is treated as strings. Ex. If you wanted to store 1.5 as "1 1/2" what's written would be a better way of determining a negative number than doing the lookup to find the numeric value and arithmetic.

Admin

actually i once managed to trick the basic interpreter on my commodore 64 to geneate -0 as result of some operation - which is case where this routing might be useful

Admin

If you really want to include -0 as a negative number (even though it's mathematically nonsensical), just do something like:

if (num < 0.0 || num == -0.0)

That assumes that 0 != -0.0 and makes no other assumptions about the various possible combinations of stupid comparisons between stupid non-numbers which only exist "because they can."