This is why I hate coldfusion. It doesn't hold to any conventions about how objects should be compared. For example, strings of different lengths get evaluated completely differently. I know of no other language that does this.
<cfscript> a = '12345'; b = '12346'; // Should be false, and is false. writeoutput('#a# eq #b# == #a eq b#<br />');
a = '2707200116272368271111'; b = '2707200116272368279465'; // Should be false, but isn't. writeoutput('#a# eq #b# == #a eq b#<br />'); </cfscript>
And I thought, "Nah, that's just with adobe's". Wrong. Railo's output:
> This is why I hate coldfusion. It doesn't hold to any conventions about > how objects should be compared. For example, strings of different > lengths get evaluated completely differently. I know of no other > language that does this.
> <cfscript> > a = '12345'; > b = '12346'; > // Should be false, and is false. > writeoutput('#a# eq #b# == #a eq b#<br />');
> a = '2707200116272368271111'; > b = '2707200116272368279465'; > // Should be false, but isn't. > writeoutput('#a# eq #b# == #a eq b#<br />'); > </cfscript>
> And I thought, "Nah, that's just with adobe's". Wrong. Railo's output:
> > This is why I hate coldfusion. It doesn't hold to any conventions about
> > how objects should be compared. For example, strings of different
> > lengths get evaluated completely differently. I know of no other
> > language that does this.
> > <cfscript>
> > a = '12345';
> > b = '12346';
> > // Should be false, and is false.
> > writeoutput('#a# eq #b# == #a eq b#<br />');
> > a = '2707200116272368271111';
> > b = '2707200116272368279465';
> > // Should be false, but isn't.
> > writeoutput('#a# eq #b# == #a eq b#<br />');
> > </cfscript>
> > And I thought, "Nah, that's just with adobe's". Wrong. Railo's output:
> > This is why I hate coldfusion. It doesn't hold to any
> conventions about
> > how objects should be compared. For example, strings of different
> > lengths get evaluated completely differently. I know of no other
> > language that does this.
> > <cfscript>
> > a = '12345';
> > b = '12346';
> > // Should be false, and is false.
> > writeoutput('#a# eq #b# == #a eq b#<br />');
> > a = '2707200116272368271111';
> > b = '2707200116272368279465';
> > // Should be false, but isn't.
> > writeoutput('#a# eq #b# == #a eq b#<br />');
> > </cfscript>
> > And I thought, "Nah, that's just with adobe's". Wrong. Railo's
> output:
This is very nice to know. I never noticed this before, I guess since I
rarely compare long strings. This is the kind of thing that could set you
back a few hours or days. :)
thx--
Ryan
>> > This is why I hate coldfusion. It doesn't hold to any conventions about
>> > how objects should be compared. For example, strings of different
>> > lengths get evaluated completely differently. I know of no other
>> > language that does this.
>> > <cfscript>
>> > a = '12345';
>> > b = '12346';
>> > // Should be false, and is false.
>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>> > a = '2707200116272368271111';
>> > b = '2707200116272368279465';
>> > // Should be false, but isn't.
>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>> > </cfscript>
>> > And I thought, "Nah, that's just with adobe's". Wrong. Railo's output:
Don't think so. It's simply an issue with precision of integers. I'm
not much of a guru on the inner workings of any of the CF engines (sad
to say), but I'm pretty sure all of them will by default treat a =
12345 OR a = '12345' as creation and assignment of an integer (or
*possibly* BigInt). If you concatenate something to them, it'll
probably treat them as strings, or if there are any non numeric
characters, but you were simply running into an issue with comparing
really large numbers.
As for Compare and CompareNoCase, they're what you'd expect. In one
abc == ABC and in the other abc !== ABC.
>> > This is why I hate coldfusion. It doesn't hold to any conventions
>> about
>> > how objects should be compared. For example, strings of different
>> > lengths get evaluated completely differently. I know of no other
>> > language that does this.
>> > <cfscript>
>> > a = '12345';
>> > b = '12346';
>> > // Should be false, and is false.
>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>> > a = '2707200116272368271111';
>> > b = '2707200116272368279465';
>> > // Should be false, but isn't.
>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>> > </cfscript>
>> > And I thought, "Nah, that's just with adobe's". Wrong. Railo's
>> output:
On Thu, May 21, 2009 at 9:47 AM, Peter Bell <pe...@pbell.com> wrote:
> Don't think so. It's simply an issue with precision of integers. I'm not
> much of a guru on the inner workings of any of the CF engines (sad to say),
> but I'm pretty sure all of them will by default treat a = 12345 OR a =
> '12345' as creation and assignment of an integer (or *possibly* BigInt). If
> you concatenate something to them, it'll probably treat them as strings, or
> if there are any non numeric characters, but you were simply running into an
> issue with comparing really large numbers.
> As for Compare and CompareNoCase, they're what you'd expect. In one abc ==
> ABC and in the other abc !== ABC.
> Best Wishes,
> Peter
> On May 21, 2009, at 10:31 AM, Tom Lenz wrote:
> Yeah, must be the reason for the Compare and CompareNoCase functions
> Ryan Letulle wrote:
> Hmmm. This is some nasty stuff. So have you determined that string
> comparisons beyond a certain length cannot be trusted.
> --
> Ryan
> On Thu, May 21, 2009 at 7:51 AM, Tom Lenz <astonishena...@gmail.com>wrote:
>> Someone suggested that maybe these strings are getting converted to
>> numbers and compared as numbers. Sure enough:
>> <cfscript>
>> a = 'xyz2707200116272368271111';
>> b = 'xyz2707200116272368279465';
>> // can't be converted to numbers
>> writeoutput('#a# eq #b# == #a eq b#<br />');
>> </cfscript>
>> > This is why I hate coldfusion. It doesn't hold to any conventions about
>> > how objects should be compared. For example, strings of different
>> > lengths get evaluated completely differently. I know of no other
>> > language that does this.
>> > <cfscript>
>> > a = '12345';
>> > b = '12346';
>> > // Should be false, and is false.
>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>> > a = '2707200116272368271111';
>> > b = '2707200116272368279465';
>> > // Should be false, but isn't.
>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>> > </cfscript>
>> > And I thought, "Nah, that's just with adobe's". Wrong. Railo's output:
It appears that you are ok if the data between quotes is interpreted as a string instead of as a number.
so this would be a number "1234567890123456789"
but "1234-5678901-23456789" would be a string.
Andrew Penhorwood
Thursday, May 21, 2009, 11:01:52 AM, you wrote:
So very large integers cannot be compared precisely but strings such uuid can?
--
Ryan
On Thu, May 21, 2009 at 9:47 AM, Peter Bell <peter@pbell.com> wrote:
Don't think so. It's simply an issue with precision of integers. I'm not much of a guru on the inner workings of any of the CF engines (sad to say), but I'm pretty sure all of them will by default treat a = 12345 OR a = '12345' as creation and assignment of an integer (or *possibly* BigInt). If you concatenate something to them, it'll probably treat them as strings, or if there are any non numeric characters, but you were simply running into an issue with comparing really large numbers.
As for Compare and CompareNoCase, they're what you'd expect. In one abc == ABC and in the other abc !== ABC.
Best Wishes,
Peter
On May 21, 2009, at 10:31 AM, Tom Lenz wrote:
Yeah, must be the reason for the Compare and CompareNoCase functions
Ryan Letulle wrote:
Hmmm. This is some nasty stuff. So have you determined that string comparisons beyond a certain length cannot be trusted.
Right. Its a function of the Java type system, but I don't know
offhand of any type system that can compare arbitrarily large numbers.
Usually you have a few types like Int, BigInt, Decimal and BigDecimal
and you need to know the limitations of the underlying system. It's
the same if you try to compare floating point numbers and run into
precision issues. I'd definitely recommend reading up on the Java type
system. CFML allows us to ignore types most of the time, but that
doesn't mean they don't exist, so you can still get caught out by them
if you're not aware of what is going on under the hood. This is true
in all computer languages (that Im aware of),
> So very large integers cannot be compared precisely but strings such
> uuid can?
> --
> Ryan
> On Thu, May 21, 2009 at 9:47 AM, Peter Bell <pe...@pbell.com> wrote:
> Don't think so. It's simply an issue with precision of integers. I'm
> not much of a guru on the inner workings of any of the CF engines
> (sad to say), but I'm pretty sure all of them will by default treat
> a = 12345 OR a = '12345' as creation and assignment of an integer
> (or *possibly* BigInt). If you concatenate something to them, it'll
> probably treat them as strings, or if there are any non numeric
> characters, but you were simply running into an issue with comparing
> really large numbers.
> As for Compare and CompareNoCase, they're what you'd expect. In one
> abc == ABC and in the other abc !== ABC.
> Best Wishes,
> Peter
> On May 21, 2009, at 10:31 AM, Tom Lenz wrote:
> Yeah, must be the reason for the Compare and CompareNoCase functions
> Ryan Letulle wrote:
> Hmmm. This is some nasty stuff. So have you determined that string
> comparisons beyond a certain length cannot be trusted.
> --
> Ryan
> On Thu, May 21, 2009 at 7:51 AM, Tom Lenz <astonishena...@gmail.com>
> wrote:
> Someone suggested that maybe these strings are getting converted to
> numbers and compared as numbers. Sure enough:
> <cfscript>
> a = 'xyz2707200116272368271111';
> b = 'xyz2707200116272368279465';
> // can't be converted to numbers
> > This is why I hate coldfusion. It doesn't hold to any conventions
> about
> > how objects should be compared. For example, strings of different
> > lengths get evaluated completely differently. I know of no other
> > language that does this.
> > <cfscript>
> > a = '12345';
> > b = '12346';
> > // Should be false, and is false.
> > writeoutput('#a# eq #b# == #a eq b#<br />');
> > a = '2707200116272368271111';
> > b = '2707200116272368279465';
> > // Should be false, but isn't.
> > writeoutput('#a# eq #b# == #a eq b#<br />');
> > </cfscript>
> > And I thought, "Nah, that's just with adobe's". Wrong. Railo's
> output:
The third compare is doing a number-to-string comparison, but the
numbers are already truncated in precision, so converting them to
strings isn't going to help. Though I get -1 for all three
statements on ColdFusion Server 8,0,1,195765
Verrry nice to know because on occasion I have used the exact point in time
as a unique id - i.e. YYYYMMDDHHMMSS
I don't think I will ever do that again.
--
Ryan
On Thu, May 21, 2009 at 10:09 AM, Andrew Penhorwood <and...@coldbits.com>wrote:
> It appears that you are ok if the data between quotes is interpreted as a
> string instead of as a number.
> so this would be a number "1234567890123456789"
> but "1234-5678901-23456789" would be a string.
> Andrew Penhorwood
> Thursday, May 21, 2009, 11:01:52 AM, you wrote:
> So very large integers cannot be compared precisely but strings such uuid
> can?
> --
> Ryan
> On Thu, May 21, 2009 at 9:47 AM, Peter Bell <pe...@pbell.com> wrote:
> Don't think so. It's simply an issue with precision of integers. I'm not
> much of a guru on the inner workings of any of the CF engines (sad to say),
> but I'm pretty sure all of them will by default treat a = 12345 OR a =
> '12345' as creation and assignment of an integer (or *possibly* BigInt). If
> you concatenate something to them, it'll probably treat them as strings, or
> if there are any non numeric characters, but you were simply running into an
> issue with comparing really large numbers.
> As for Compare and CompareNoCase, they're what you'd expect. In one abc ==
> ABC and in the other abc !== ABC.
> Best Wishes,
> Peter
> On May 21, 2009, at 10:31 AM, Tom Lenz wrote:
> Yeah, must be the reason for the Compare and CompareNoCase functions
> Ryan Letulle wrote:
> Hmmm. This is some nasty stuff. So have you determined that string
> comparisons beyond a certain length cannot be trusted.
> --
> Ryan
> On Thu, May 21, 2009 at 7:51 AM, Tom Lenz <astonishena...@gmail.com>
> wrote:
> Someone suggested that maybe these strings are getting converted to
> Verrry nice to know because on occasion I have used the exact point
> in time as a unique id - i.e. YYYYMMDDHHMMSS
> I don't think I will ever do that again.
> --
> Ryan
> On Thu, May 21, 2009 at 10:09 AM, Andrew Penhorwood <and...@coldbits.com > > wrote:
> Ryan,
> It appears that you are ok if the data between quotes is interpreted
> as a string instead of as a number.
> so this would be a number "1234567890123456789"
> but "1234-5678901-23456789" would be a string.
> Andrew Penhorwood
> Thursday, May 21, 2009, 11:01:52 AM, you wrote:
> So very large integers cannot be compared precisely but strings such
> uuid can?
> --
> Ryan
> On Thu, May 21, 2009 at 9:47 AM, Peter Bell <pe...@pbell.com> wrote:
> Don't think so. It's simply an issue with precision of integers. I'm
> not much of a guru on the inner workings of any of the CF engines
> (sad to say), but I'm pretty sure all of them will by default treat
> a = 12345 OR a = '12345' as creation and assignment of an integer
> (or *possibly* BigInt). If you concatenate something to them, it'll
> probably treat them as strings, or if there are any non numeric
> characters, but you were simply running into an issue with comparing
> really large numbers.
> As for Compare and CompareNoCase, they're what you'd expect. In one
> abc == ABC and in the other abc !== ABC.
> Best Wishes,
> Peter
> On May 21, 2009, at 10:31 AM, Tom Lenz wrote:
> Yeah, must be the reason for the Compare and CompareNoCase functions
> Ryan Letulle wrote:
> Hmmm. This is some nasty stuff. So have you determined that string
> comparisons beyond a certain length cannot be trusted.
> --
> Ryan
> On Thu, May 21, 2009 at 7:51 AM, Tom Lenz <astonishena...@gmail.com>
> wrote:
> Someone suggested that maybe these strings are getting converted to
On Thu, May 21, 2009 at 9:16 AM, Peter Bell <pe...@pbell.com> wrote:
> Add hyphens. More readable and clearly a string :-)
> DateFormat( Now() , "YYYY-MM-DD-HH-MM-SS")
> Best Wishes,
> Peter
> On May 21, 2009, at 12:06 PM, Ryan Letulle wrote:
> Verrry nice to know because on occasion I have used the exact point in time
> as a unique id - i.e. YYYYMMDDHHMMSS
> I don't think I will ever do that again.
> --
> Ryan
> On Thu, May 21, 2009 at 10:09 AM, Andrew Penhorwood <and...@coldbits.com>wrote:
>> Ryan,
>> It appears that you are ok if the data between quotes is interpreted as a
>> string instead of as a number.
>> so this would be a number "1234567890123456789"
>> but "1234-5678901-23456789" would be a string.
>> Andrew Penhorwood
>> Thursday, May 21, 2009, 11:01:52 AM, you wrote:
>> So very large integers cannot be compared precisely but strings such
>> uuid can?
>> --
>> Ryan
>> On Thu, May 21, 2009 at 9:47 AM, Peter Bell <pe...@pbell.com> wrote:
>> Don't think so. It's simply an issue with precision of integers. I'm not
>> much of a guru on the inner workings of any of the CF engines (sad to say),
>> but I'm pretty sure all of them will by default treat a = 12345 OR a =
>> '12345' as creation and assignment of an integer (or *possibly* BigInt). If
>> you concatenate something to them, it'll probably treat them as strings, or
>> if there are any non numeric characters, but you were simply running into an
>> issue with comparing really large numbers.
>> As for Compare and CompareNoCase, they're what you'd expect. In one abc ==
>> ABC and in the other abc !== ABC.
>> Best Wishes,
>> Peter
>> On May 21, 2009, at 10:31 AM, Tom Lenz wrote:
>> Yeah, must be the reason for the Compare and CompareNoCase functions
>> Ryan Letulle wrote:
>> Hmmm. This is some nasty stuff. So have you determined that string
>> comparisons beyond a certain length cannot be trusted.
>> --
>> Ryan
>> On Thu, May 21, 2009 at 7:51 AM, Tom Lenz <astonishena...@gmail.com>
>> wrote:
>> Someone suggested that maybe these strings are getting converted to
Everything simple is a string, it's defacto since a string can hold
everything. I imagine most of the engines store all CF level data in some
sort of CFML Data wrapper so reality is nothing is stored as a int or as a
string but really as an object but I think that goes beyond the discussion
here. The important thing to note is that CFML engines will convert a value
at runtime to the "appropriate type".
Very large integers *can *be compared precisely. Very large *numbers*, which
are not integers, may not be able to be compared precisely. This is more
than a semantic distinction there is a difference. Realize that regardless
of how a value is "stored" when the comparison happens it happens in Java so
the number must be representable as a number in java in some type or
another. Longs, the largest primative numeric type in Java as far as I
recall, have the range of around +/- 1x10^19 (the range is actually smaller
than that but this was easier to type). The original numbers set forth are
larger than this which might be why there are recorded inconsistencies. I
think Larger numbers can be cast into BigIntegers but that's not native and
i am not sure how BigIntegers perform, can't say I've ever run into the need
to know about it.
On Thu, May 21, 2009 at 11:01 AM, Ryan Letulle <bayous...@gmail.com> wrote:
> So very large integers cannot be compared precisely but strings such uuid
> can?
> --
> Ryan
> On Thu, May 21, 2009 at 9:47 AM, Peter Bell <pe...@pbell.com> wrote:
>> Don't think so. It's simply an issue with precision of integers. I'm not
>> much of a guru on the inner workings of any of the CF engines (sad to say),
>> but I'm pretty sure all of them will by default treat a = 12345 OR a =
>> '12345' as creation and assignment of an integer (or *possibly* BigInt). If
>> you concatenate something to them, it'll probably treat them as strings, or
>> if there are any non numeric characters, but you were simply running into an
>> issue with comparing really large numbers.
>> As for Compare and CompareNoCase, they're what you'd expect. In one abc ==
>> ABC and in the other abc !== ABC.
>> Best Wishes,
>> Peter
>> On May 21, 2009, at 10:31 AM, Tom Lenz wrote:
>> Yeah, must be the reason for the Compare and CompareNoCase functions
>> Ryan Letulle wrote:
>> Hmmm. This is some nasty stuff. So have you determined that string
>> comparisons beyond a certain length cannot be trusted.
>> --
>> Ryan
>> On Thu, May 21, 2009 at 7:51 AM, Tom Lenz <astonishena...@gmail.com>wrote:
>>> Someone suggested that maybe these strings are getting converted to
>>> numbers and compared as numbers. Sure enough:
>>> <cfscript>
>>> a = 'xyz2707200116272368271111';
>>> b = 'xyz2707200116272368279465';
>>> // can't be converted to numbers
>>> writeoutput('#a# eq #b# == #a eq b#<br />');
>>> </cfscript>
>>> gives what you'd want with Railo:
>>> 270720011627236821111
>>> with adobe cf:
>>> Context validation error for the cfcase tag.
>>> The cfswitch tag has a duplicate cfcase tag for value
>>> 2.7072001162723682E20.
>>> > This is why I hate coldfusion. It doesn't hold to any conventions about
>>> > how objects should be compared. For example, strings of different
>>> > lengths get evaluated completely differently. I know of no other
>>> > language that does this.
>>> > <cfscript>
>>> > a = '12345';
>>> > b = '12346';
>>> > // Should be false, and is false.
>>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>>> > a = '2707200116272368271111';
>>> > b = '2707200116272368279465';
>>> > // Should be false, but isn't.
>>> > writeoutput('#a# eq #b# == #a eq b#<br />');
>>> > </cfscript>
>>> > And I thought, "Nah, that's just with adobe's". Wrong. Railo's output:
the problem is and yes it is a problem, in java numbers are restricted in (byte) size.
Railo use internally double values for all number operations.
it is possible to use BigDecimal but this is very slow.
what is happening in your example, a cfml string comparsion always check if the 2 operant are castable to numeric value.
if yes in make a number comparsion otherwise a string comparision:
example:
<cfoutput>#"01" EQ "1"#</cfoutput> return true, because both values cant be translated to 1.
ok let us take your example
<cfscript>
a = '2707200116272368271111';
b = '2707200116272368279465';
writeoutput(a+0);
writeoutput('<br>');
writeoutput(a+0);
</cfscript>
the plus 0 translate the value to a number
the output is
2707200116272368000000
2707200116272368000000
and a comparsion of this 2 values gives true
the question is why are this values transalted to the same numeric value.
take the following example
<cfscript>
Double=createObject('java','java.lang.Double');
a = '2707200116272368271111';
b = '2707200116272368279465';
writeoutput(Double.toString(Double.parseDouble(a)));
writeoutput('<br>');
writeoutput(Double.toString(Double.parseDouble(b)));
</cfscript>
you see i use a native java method to translate the string to a number and back to a string and the result is the same for both vaules.
the problem is already on java level
you can also see this problem also with smaller numbers
<cf_valueEquals left="#(27^(1/3))#" right="3">
output:2.99999999997
> the problem is and yes it is a problem, in java numbers are restricted > in (byte) size. > Railo use internally double values for all number operations. > it is possible to use BigDecimal but this is very slow.
What about using BigDecimal only for values greater than <Doble_Limit>?
Example: the same way you check it "01" should be compared either as a string or as a number, you can check it can be compared either as a double or as a bigdecimal.