Skip to main content
Known Participant
January 9, 2013
Answered

Possible comparison bug

  • January 9, 2013
  • 2 replies
  • 1078 views

Hi all,

There's a good one, which may have an obvious answer (and that's the reason I first decided to ask it here before filing a bug).

<cfset t1 = ToString("00237000000075384887")>

<cfset t2 = ToString("00237000000075384892")>

<cfif t1 EQ t2><cfoutput>#t1# equal to #t2#</cfoutput><cfelse><cfoutput>#t1# different to #t2#</cfoutput></cfif>

The result of the above is rather surprising. Somewhat this sort of comparison thinks the numbers are equal. Also, even if both numbers are converted to strings,  ColdFusion still thinks they are equal.

If using Compare(t1,t2) however, ColdFusion starts comparing the strings as us, humans and distinguishes the difference between them



Now if there's any known limitation to comparing long numbers etc. or the fact that middle of each of them is filled with zeros affects it all, be welcome to point it out to me.



Simon

    This topic has been closed for replies.
    Correct answer Adam Cameron.

    Do some google on "floating point precision".

    As CF is loosely typed, it has to make some guesses when it comes to doing operations in which type is significant. The EQ operator is an example of this: if CF can cast the operands to numerics, it will, which is what it's doing here. And when it casts those strings to numerics, both are 2.37000000075E+017, so they equal.

    If you want to compare two strings explicitly as strings, then you need to use compare(), as you ahve already surmised.

    There are no surprises in anything you're seeing though.

    --

    Adam

    2 replies

    12Robots
    Participating Frequently
    January 9, 2013

    You can use PrecisionEvaluate() to have CF store those numbers as BigDecimal instead of Double. You'll likely then see the behavior you expect.

    Jason

    Simon.DauAuthor
    Known Participant
    January 9, 2013

    Thanks guys!

    @12Robots: tried PrecisionEvaluate(), though results were the same.

    @Adam Cameron: Thanks for the explanation. Thought there's something there I've missed. Well, learned something new today

    Inspiring
    January 9, 2013

    I would have expected precisionEvaluate() to work, but I can't coerce it into being helpful here.  But one can cut to the chase and just use BigDecimals:

    <cfset t1 = createObject("java", "java.math.BigDecimal").init("00237000000075384887")>

    <cfset t2 = createObject("java", "java.math.BigDecimal").init("00237000000075384892")>

    <cfoutput>#t1.compareTo(t2)#<br /></cfoutput>

    That works fine.

    --

    Adam

    Adam Cameron.Correct answer
    Inspiring
    January 9, 2013

    Do some google on "floating point precision".

    As CF is loosely typed, it has to make some guesses when it comes to doing operations in which type is significant. The EQ operator is an example of this: if CF can cast the operands to numerics, it will, which is what it's doing here. And when it casts those strings to numerics, both are 2.37000000075E+017, so they equal.

    If you want to compare two strings explicitly as strings, then you need to use compare(), as you ahve already surmised.

    There are no surprises in anything you're seeing though.

    --

    Adam