• flyboyfred (unregistered) in reply to twatter
    twatter:
    TRWTF is that Java was born in 1991 and was, in that fase, not yet that usable.

    So I'm not sure what his 20 years of experience were, but them being in Java is scientifically impossible.

    The article doesn't say 20 years of Java experience. It says a 20-year veteran with great Java experience. See the difference?

  • (cs) in reply to Henning Makholm
    Henning Makholm:
    Gumpy Guss:
    Next as many others have mentioned, you should think about what you mean by "equal". Floating-point numbers can have up to 128 bits of significance and can go down to 10^-308 or so. Do you really want to consider 1.0000000000001E-302 different from 1.0000000002E-302?
    If you're implementing java.lang.Comparable, then: Yes, definitely so. Its contract is that compareTo implements a total preorder. There MUST NOT be any a, b and c where a.compareTo(b)==0 and b.compareTo(c)==0 yet a.compareTo(c)>0. If this is violated -- as your proposal would -- lots of standard sorting or container algorithms can get very confused.

    In these contexts one is typically not terribly concerned with whether two close values compare as equal or different, so long as what they do is consistent with all other comparisons.

    Technically, round-before-compare would satisfy this - the set of all values that round to a given value would comprise an equivalence class. There would be some "really close" values that round in different directions, of course, but ideally you shouldn't actually be working with such values, but rather only working with values that are close to the center of their equivalence class (i.e. close to the value they round to)

  • AdT (unregistered) in reply to Its an INT compare
    Its an INT compare:
    So why are you worried about that code inside? It is an ***INT*** compare, so since there aren't decimals in integers, 3.1 and 3.2 *ARE* equal.... You need to consider using the decimal compare if you want to know whether 3.1= 3.2.

    My Java is broken then. Both "twenty-five".compareTo("hundred") and "zweiundvierzig".compareTo("un million") return a value greater than zero...

  • Stop with the first crap (unregistered)

    The "first", "second", "first", etc comments will destroy this site, as they have destroyed many others. Please stop if you like this site.

  • Henning Makholm (unregistered) in reply to Random832
    Random832:
    Henning Makholm:
    Gumpy Guss:
    Do you really want to consider 1.0000000000001E-302 different from 1.0000000002E-302?
    If you're implementing java.lang.Comparable, then: Yes, definitely so. Its contract is that compareTo implements a total preorder.
    Technically, round-before-compare would satisfy this
    Yes, but why would you want to? Comparing the original floats gives you a perfectly good total order already. Usually when you want a sorting key for something, you want it to distinguish as much as possible.
  • (cs) in reply to SCB
    SCB:
    Eh:
    B. Grenger:
    I could have downloaded and installed Eclipse and had Eclipse do the compareTo() method for me in about 15 mintues.

    I think it's time you got a faster computer ...

    That 15 minutes probably includes the "download and install" time.
    Its actually all the IDE startup time!
  • jay (unregistered) in reply to SCB
    SCB:
    ubersoldat:
    SCB:
    Eh:
    B. Grenger:
    I could have downloaded and installed Eclipse and had Eclipse do the compareTo() method for me in about 15 mintues.

    I think it's time you got a faster computer ...

    That 15 minutes probably includes the "download and install" time.

    Then he need to upgrade his DSL line

    Yes, you're right. Eclipse docs say you need around 140 megabytes disk space. Assuming that this is zipped down to 70 megabytes for downloading, on an 8 megabit broadband connection this should still take less than 90 seconds. I don't know how long the installation takes though...

    You're not allowing for the time to find the IE icon on his desktop, click it, type in "www.eclipse.org", find the download button, etc.

    Like so many IT people, you've completed neglected the human interaction part of the task!

  • Alex (unregistered) in reply to Henning Makholm
    Henning Makholm:
    Gumpy Guss:
    Next as many others have mentioned, you should think about what you mean by "equal". Floating-point numbers can have up to 128 bits of significance and can go down to 10^-308 or so. Do you really want to consider 1.0000000000001E-302 different from 1.0000000002E-302?
    If you're implementing java.lang.Comparable, then: Yes, definitely so. Its contract is that compareTo implements a total preorder. There MUST NOT be any a, b and c where a.compareTo(b)==0 and b.compareTo(c)==0 yet a.compareTo(c)>0. If this is violated -- as your proposal would -- lots of standard sorting or container algorithms can get very confused.

    In these contexts one is typically not terribly concerned with whether two close values compare as equal or different, so long as what they do is consistent with all other comparisons.

    Because Java truncates instead of rounds, I'm pretty sure that this requirement isn't violated. I'm too lazy to actually figure it out though.

  • Anonymous (unregistered) in reply to Zapp Brannigan
    Zapp Brannigan:
    The consultant was probably experienced in another language and was new to java.

    Article: "added a 'twenty-year veteran' with 'great Java experience' to my team"

  • OldCoder (unregistered) in reply to Its an INT compare
    Its an INT compare:
    So why are you worried about that code inside? It is an ***INT*** compare, so since there aren't decimals in integers, 3.1 and 3.2 *ARE* equal.... You need to consider using the decimal compare if you want to know whether 3.1= 3.2.
    So... you're saying that 3.2 would be considered equal, whereas 3.95 would not be considered equal to 4.00, even though the difference between the two values is less?
  • OldCoder (unregistered) in reply to OldCoder
    OldCoder:
    Its an INT compare:
    So why are you worried about that code inside? It is an ***INT*** compare, so since there aren't decimals in integers, 3.1 and 3.2 *ARE* equal.... You need to consider using the decimal compare if you want to know whether 3.1= 3.2.
    So... you're saying that 3.1 and 3.2 would be considered equal, whereas 3.95 would not be considered equal to 4.00, even though the difference between the two values is less?
    Fixed.
  • Squire (unregistered) in reply to Zapp Brannigan

    If someone is being brought in as a contractor to perform a specific function and is being paid a (probably) considerable sum of money for their work no one else being paid by that same employer should have to teach them anything. They aren't there to get an education, they are there to perform a specific duty for a specific amount of money.

    If he wants to learn Java, he should practice on his own or take a continuing education course and stop wasting other peoples' time and money.

  • Anne (unregistered) in reply to Alex (yes there are more then one)
    Alex (yes there are more then one):
    Surely you know that one can never fix a project by adding more staff in the late stages of a project to make up the time.

    Yep, to me that was the real WTF in the whole story. Brooks' Law: "Adding manpower to a late software project makes it later." (Fred Brooks, "The Mythical Man-Month", 1975.)

    Too bad that Zarar and the Powers That Be that he reports to 1) had never heard of Brooks' law, or 2) felt compelled to prove the truth of it. (Well, I guess he succeeded on the second point at least.)

  • Gaspar (unregistered) in reply to Moe

    I respectfully suggest you stop smoking crack...

    So first off, a float consists of mathematical concept AND A SET O BITS.

    The bits are NEVER imprecise. They always have a precise value. Further more, if you compare two floats in the suggested environment, barring a sun flare altering bits in ram/registers/buffers they will react the same as two ints.

    As for the consultant's work. His second deliverable would be fine (if over complicated) except that it adds in a buffer overflow exception issue.

  • Roy Underthump (unregistered) in reply to Zapp Brannigan

    The terrors of floating point apply to all languages, and he should have known that his code was dicey. And using ints without the two decimal places in the first place was inexcusable.

  • (cs) in reply to monkeyPushButton
    monkeyPushButton:
    fw:
    frist!
    Being a site about programming, shouldn't the first poster be 0th?
    Jeez, the article is number 0, so the comments start at 1. Couldn't you have figured out that by yourself?
  • Duke of New York (unregistered) in reply to Moe
    Moe:
    Although I guess the contractor didn't know that, his method is better than it looks. Comparing floats is inherently difficult
    Yeah, it's so inherently difficult that every frigging programming language has the correct method built in, so that the "twenty year veterans" of the world don't have to spend time on it.
    Moe:
    His second attempt is a valid compareTo implementation assuming two decimals precision throughout the application.
    Milking a horse is valid assuming that the horse is a cow.
  • (cs) in reply to Gaspar
    Gaspar:
    So first off, a float consists of mathematical concept AND A SET O BITS.

    The bits are NEVER imprecise. They always have a precise value. Further more, if you compare two floats in the suggested environment, barring a sun flare altering bits in ram/registers/buffers they will react the same as two ints.

    Oh, they can be imprecise. Don't fool yourself. If variables are stored as double precision - 64 bits - and calculations are done internally with 80 bits (which is a pretty common situation), you are bound to run into strange errors.

    x = 1.0/3.0; if (x==1.0/3.0) ...

    where 1.0/3.0 is an 80 bit number, while x is a 64 bit number. Not equal!

    Anyway, given that this is Java, could you explain the phrase "Sun flare" please?

  • Some Guy (unregistered)
    "With more changes being requested by the business and less time allowed to turn around those changes, we've fallen a bit behind on our deadlines," ... "It mostly went downhill from there. And yes, I'm still coming in the office, weekend after weekend."

    You realize this part is entirely your fault. Set realistic expectations. If the deadlines are impossible, speak up. If they got you a contractor and he sucks, speak up.

    It amazes me when developers are given projects and timelines they know are impossible, and rather than correct managers and set realistic expectations they simply work longer hours.

    Now, I'm certainly familiar with putting in the time, weekends, late nights, whatever. But that should be the exception rather than the norm.

  • GiantPenises (unregistered)

    Wait, would this work? if x = y then ... else ...

  • (cs) in reply to Pim
    Pim:
    Anyway, given that this is Java, could you explain the phrase "Sun flare" please?
    Surely you need to consult the Oracle.
  • Americium (unregistered) in reply to B. Grenger
    B. Grenger:
    I could have downloaded and installed Eclipse and had Eclipse do the compareTo() method for me in about 15 mintues.

    Then, you could have ordered an extra 2Gb of RAM and waited two weeks for it to be installed. After that, Eclipse would start working.

  • Bean (unregistered)

    Not sure why when I hear "20 Years experience" and "Java" in the same sentence, alarm bells are ringing.....

    Those 20 Cobol years were probably invaluable, though...

  • John (unregistered) in reply to stEvil
    stEvil:
    Alex (yes there are more then one):
    Surely you know that one can never fix a project by adding more staff in the late stages of a project to make up the time...

    no, but I admire their scapegoat-diversification scheme!

    Ah, The Mythical Man-Month!!

  • Americium (unregistered) in reply to Duke of New York
    Duke of New York:
    Moe:
    Although I guess the contractor didn't know that, his method is better than it looks. Comparing floats is inherently difficult
    Yeah, it's so inherently difficult that every frigging programming language has the correct method built in, so that the "twenty year veterans" of the world don't have to spend time on it.
    Moe:
    His second attempt is a valid compareTo implementation assuming two decimals precision throughout the application.
    Milking a horse is valid assuming that the horse is a cow.

    Horse milk is commonly drank by Mongolians. Any placental mammal has teats big enough to milk. Don't try this on a platypus, since they only have glands, not nipples.

    Better yet, don't make analogy arguments unless you know what you're talking about.

  • Mathias (unregistered) in reply to Henning Makholm
    Henning Makholm:
    Gumpy Guss:
    Next as many others have mentioned, you should think about what you mean by "equal". Floating-point numbers can have up to 128 bits of significance and can go down to 10^-308 or so. Do you really want to consider 1.0000000000001E-302 different from 1.0000000002E-302?
    If you're implementing java.lang.Comparable, then: Yes, definitely so. Its contract is that compareTo implements a total preorder. There MUST NOT be any a, b and c where a.compareTo(b)==0 and b.compareTo(c)==0 yet a.compareTo(c)>0. If this is violated -- as your proposal would -- lots of standard sorting or container algorithms can get very confused.

    In these contexts one is typically not terribly concerned with whether two close values compare as equal or different, so long as what they do is consistent with all other comparisons.

    sure, but if two close values are equal (lets say a & b), and two other close values are considered equal (this time b & c), the gap betweeen a & c may be greater than the gap between a & b, and a & c may not be equal.
    In other words, what you said in your last paragraph seems to contradict the earlier part of your post....

    Or have I forgotten to put my thinking cap on??

  • Jorg (unregistered) in reply to twatter
    twatter:
    TRWTF is that Java was born in 1991 and was, in that fase, not yet that usable.

    So I'm not sure what his 20 years of experience were, but them being in Java is scientifically impossible.

    Captcha: facilisis (not a clue what it is, but it sounds gross)

    True, but the article never said Java experience, just experience.
    Theoretically, you know programming concepts well, you should be able to pick up most languages reasonably easily...That of course is a wonderful theory. Not sure how well someone who has used Ada (for example) for 20 years would go about picking up Lisp (for another example), though....

    waiting.....

  • Bucket (unregistered) in reply to Stop with the first crap
    Stop with the first crap:
    The "first", "second", "first", etc comments will destroy this site, as they have destroyed many others. Please *stop* if you like this site.
    And while those comments are annoying the one whinging about them aren't much better....

    OOPS!!!

  • Jocvk (unregistered) in reply to Henning Makholm
    Henning Makholm:
    Random832:
    Henning Makholm:
    Gumpy Guss:
    Do you really want to consider 1.0000000000001E-302 different from 1.0000000002E-302?
    If you're implementing java.lang.Comparable, then: Yes, definitely so. Its contract is that compareTo implements a total preorder.
    Technically, round-before-compare would satisfy this
    Yes, but why would you want to? Comparing the original floats gives you a perfectly good total order already. Usually when you want a sorting key for something, you want it to distinguish as much as possible.

    I think the point is that to maintain transitivity, you should round first...

    Otherwise while there appears to be more accuracy, a result relationships a->b, b->c, b->c (specifically one that considers a close enough to b to be equal, and b close enough to c to be equal, but not a to c) may show inconsistent behaviour.

    Rounding to the accuracy you want first, ensures that transitivity will still hold, because one of a, b, or c would be rounded to a different number, so we might have a=b, b<c, a<c etc....

    Rereading this, it doesn't make much sense, but I know hwat I mean (and that be the important bit)

  • Alexis (unregistered) in reply to Alex
    Alex:
    Henning Makholm:
    Gumpy Guss:
    Next as many others have mentioned, you should think about what you mean by "equal". Floating-point numbers can have up to 128 bits of significance and can go down to 10^-308 or so. Do you really want to consider 1.0000000000001E-302 different from 1.0000000002E-302?
    If you're implementing java.lang.Comparable, then: Yes, definitely so. Its contract is that compareTo implements a total preorder. There MUST NOT be any a, b and c where a.compareTo(b)==0 and b.compareTo(c)==0 yet a.compareTo(c)>0. If this is violated -- as your proposal would -- lots of standard sorting or container algorithms can get very confused.

    In these contexts one is typically not terribly concerned with whether two close values compare as equal or different, so long as what they do is consistent with all other comparisons.

    Because Java truncates instead of rounds, I'm pretty sure that this requirement isn't violated. I'm too lazy to actually figure it out though.

    I think it depends whether the truncation is before the calculation, or on the actual result. If it's the result that gets truncated, this requirement is (I boldly think) violated...

  • Javalizer (unregistered)

    Isn't this easier than discussing rounding and bitwise representation of floats for hours?

    public int compareTo (Object obj) { return Float.compare(getVarianceAmount(), ((OfferedActivity)obj).getVarianceAmount())); }

    Let Java do it! (and let it take care of some corner cases as well) Granted this method (and the original one) assumes that obj is actually an instance of OfferedActivity, so some parameter checking would be in order.

  • Robert Scholte (unregistered) in reply to jan

    In such cases I always have a look at commons-lang: return org.apache.commons.lang.math.NumberUtils.compare(f1, f2)

    it's just a matter of taste, I guess

  • dan (unregistered) in reply to SCB
    SCB:
    ... Assuming that this is zipped down to 70 megabytes for downloading, on an 8 megabit broadband connection this should still take less than 90 seconds. I don't know how long the installation takes though...

    Remind me to never let you estimate any of my projects.

  • Its an INT compare (unregistered) in reply to OldCoder
    OldCoder:
    OldCoder:
    Its an INT compare:
    So why are you worried about that code inside? It is an ***INT*** compare, so since there aren't decimals in integers, 3.1 and 3.2 *ARE* equal.... You need to consider using the decimal compare if you want to know whether 3.1= 3.2.
    So... you're saying that 3.1 and 3.2 would be considered equal, whereas 3.95 would not be considered equal to 4.00, even though the difference between the two values is less?
    Fixed.

    Again I ask, why are you sending a decimal to an int comparer? A method designed for dealing with non-decimal numbers.

  • (cs) in reply to Stop with the first crap
    Stop with the first crap:
    The "first", "second", "first", etc comments will destroy this site, as they have destroyed many others. Please *stop* if you like this site.
    Trouble is, the people posting them don't seem to realise that they might as well be posting "I am a wanker".
  • (cs) in reply to Its an INT compare
    Its an INT compare:
    OldCoder:
    OldCoder:
    Its an INT compare:
    So why are you worried about that code inside? It is an ***INT*** compare, so since there aren't decimals in integers, 3.1 and 3.2 *ARE* equal.... You need to consider using the decimal compare if you want to know whether 3.1= 3.2.
    So... you're saying that 3.1 and 3.2 would be considered equal, whereas 3.95 would not be considered equal to 4.00, even though the difference between the two values is less?
    Fixed.

    Again I ask, why are you sending a decimal to an int comparer? A method designed for dealing with non-decimal numbers.

    I think people mostly ignored you the first time because no one knew what you were talking about.

    What do you mean by "int comparer"? This method is comparing two objects of type Activity by comparing the values returned by the objects' getVarianceAmount methods. It is stated in the article that getVarianceAmount() returns a float, not an int.

    Are you confused by the int return type on the compareTo() method? In Java, Comparable.compareTo() returns an int that is less than zero, zero, or greater than zero depending on whether the argument is less than, equal to, or greater than the object on which it is called. The fact that the method's return type is int has nothing to do with how the comparison is to be made.

  • Tim Burr (unregistered)

    Speaking of comparison, ran across this snippet this morning

    if (dependantObject.Equals(null))
           throw new ArgumentNullException("dependantObject");
    
  • =|)arkSprout= (unregistered)

    My guess is that new consultant of 20 years learnt his stuff at the: cue joke

    The Brillant School of Java Dean: Paula Bean

    (I thank you..)

  • (cs) in reply to keeperofkeys
    keeperofkeys:
    Stop with the first crap:
    The "first", "second", "first", etc comments will destroy this site, as they have destroyed many others. Please *stop* if you like this site.
    Trouble is, the people posting them don't seem to realise that they might as well be posting "I am a wanker".

    Whoa, now, that might be a bit insulting to all the true wankers on this site. After all, they may be wankers, but you can't seriously think that's as bad as being a "first/frist/fist/whatever" in the grand scheme of things!

  • (cs) in reply to Jorg
    Jorg:
    but the article never said Java experience, just experience.
    Awww... your comment would have had so much more impact if you'd just read the article more carefully. See, it does say Java experience. What it doesn't say however, is 20 years of experience, only 'twenty-year veteran'. Whatever that means.
  • Koen (unregistered) in reply to Stop with the first crap

    95th!

  • (cs) in reply to Pim
    Pim:
    Gaspar:
    So first off, a float consists of mathematical concept AND A SET O BITS.

    The bits are NEVER imprecise. They always have a precise value. Further more, if you compare two floats in the suggested environment, barring a sun flare altering bits in ram/registers/buffers they will react the same as two ints.

    Oh, they can be imprecise. Don't fool yourself. If variables are stored as double precision - 64 bits - and calculations are done internally with 80 bits (which is a pretty common situation), you are bound to run into strange errors.

    x = 1.0/3.0; if (x==1.0/3.0) ...

    where 1.0/3.0 is an 80 bit number, while x is a 64 bit number. Not equal!

    Or this, in C on a Sun box here:
    double  x = 1761.41 / 251.63;   /* should be exactly 7 */
    

    printf("x is %.60f\n", x);

    Output is:

    x is 7.000000000000000888178419700125232338905334472656250000000000
    
    

    (That's 7 + 2^-50.)

  • (cs) in reply to pitchingchris
    pitchingchris:
    Coincoin:
    <snip> Hiring a contractor 'to catch up' is a nice one though. Never heard it before.

    Theres a reason for that. Its a bad idea. <snip>

    Sad thing is, I've been on a "6 month" project where we hired our third group of contractors 'to catch up' just before we entered year three of the project...

    It seems, some people just don't want to learn.

  • fdizzle (unregistered)

    You're still coming in the office?! WTF?

  • alex (unregistered)

    yes,when you think how not to compare to,but it is compare to it.

Leave a comment on “How Not to compareTo()”

Log In or post as a guest

Replying to comment #:

« Return to Article