• foobar (unregistered)

    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.

  • Jack (unregistered)

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

  • xellos (unregistered)

    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.

  • ifdef (unregistered)

    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..."

    :)

  • Chris R. Timmons (unregistered)

    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").

  • mrd (unregistered)

    Is -0.0 less than 0.0?

  • Dave Mays (unregistered)

    I would guess it's badly transcribed C#.

  • Alex Papadimoulis (unregistered)

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

    :-D

  • Phil Scott (unregistered)

    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.

  • Christian Duhard (unregistered)

    No idea what language this code is.

    If it's legitimate, wow.

  • Christian Duhard (unregistered)

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

  • Dave Mays (unregistered)

    while(nstr != nStr)
    {
    //noop
    }

  • WanFactory (unregistered)

    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

  • chandler (unregistered)

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

  • Guayo (unregistered)

    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;
    }

  • JeffS (unregistered)

    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.

  • Guayo (unregistered)

    @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.

  • andrei (unregistered)

    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.)

  • Jeff S (unregistered)

    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?

  • WanFactory (unregistered)

    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...

  • Guayo (unregistered)

    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.

  • Wojo (unregistered)

    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? :-)

  • Guayo (unregistered)

    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#.

  • Guayo (unregistered)

    @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. ;-)

  • Wojo (unregistered)

    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#?

  • Hassan Voyeau (unregistered)

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

  • Hassan Voyeau (unregistered)
  • andy brummer (unregistered)

    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.

  • heywood j'blomi (unregistered)


    //return whether a double is less than Pi
    bool IsLessThanPi(double n)
    {
    return IsNegative(n - 3.1415926);
    }

  • Zka (unregistered)

    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 :]

  • Zka (unregistered)

    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( nn)[ 1] in ['0','1','2','3','4','5','6','7','8','9']
    end;

    function IsPositive( n : double) : boolean;
    begin
    Result := not( FloatToStr( n
    n)[ 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;

  • Zka (unregistered)

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

  • The man with the mask ;-) (unregistered)

    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...

  • Sam (unregistered)

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

    ?

  • Ray S (unregistered)

    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

  • foxyshadis (unregistered)

    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).

  • Alan Bellingham (unregistered)

    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.

  • Zka (unregistered)

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

  • Tony (unregistered)

    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.

  • Dave M. (unregistered)

    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?

  • Alex Papadimoulis (unregistered)

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

  • nobody (unregistered)

    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>

  • Guayo (unregistered)

    @Alan Bellingham
    AFAIK...
    NegativeInfinity != NaN
    sqrt(-1) == NaN
    1/0 == PositiveInfinity
    -1/0 == NegativeInfinity
    NegativeInfinity < MinValue < MaxValue < PositiveInfinity

  • Guayo (unregistered)

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

  • Guayo (unregistered)

    @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

  • Alex Papadimoulis (unregistered)

    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 ;-).

  • Jeff S (unregistered)

    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.

  • Miles Archer (unregistered)

    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.

  • me (unregistered)

    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

  • fluffy (unregistered)

    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."

Leave a comment on “When (n<0) won't do.”

Log In or post as a guest

Replying to comment #:

« Return to Article