ColdFusion large number comparison - coldfusion

ColdFusion thinks 10090000000557765 = 10090000000557763.
I get why but I need to know the best way for ColdFusion to know they are NOT the same. I read about the Compare() method but that also returns true. I've casted them as strings and also returns true.
I thought about writing a custom function to break the string into two parts, compare each individually and then return true/false but that seems dumb.
I've Tried the following:
Val(a) EQ Val(b)
ToString(a) EQ ToString(b)
a.compareTo(b)
For clarification. I'm using a DB I don't control that uses bigint. I learned early on that Javascript couldn't handle these so I converted all the bigint fields to varchar in my models. Now however, CF is having issue comparing the strings and I can't it seems convert them back to numbers.
Example I just did:
<cfif '10090000000557765' EQ '10090000000557763'>
True
<cfelse>
False
</cfif>
On http://cflive.net/ and it returned true. See my note. In the DB they are bigint. I had to cast them as VarChar when getting them out because Javascript can't handle bigint but it does strings just fine.

Short Answer: So as not to overlook the obvious, java methods like Long.compareTo() return -1, 0, or 1. Make sure you are using the correct expression to test for equality. The result will be 0 when the values are equal. (Zero (0) evaluates to false in CF).
Longer answer:
How the values are stored, retrieved and specifically evaluated is very relevant here. All of the methods you mentioned worked fine for me under CF11 (with the exception of val, for obvious reasons). Which suggests something is different in your code or environment.
For example, using CF11 and SQL Server:
CREATE TABLE test
(
bigIntValue1 BIGINT
, bigIntValue2 BIGINT
, varcharValue1 VARCHAR(50)
, varcharValue2 VARCHAR(50)
)
The following test code:
writeOutput("<br>qry.bigIntValue1: "& val(qry.bigIntValue1) );
writeOutput("<br>qry.bigIntValue2: "& val(qry.bigIntValue2) );
writeOutput("<br>BigInt Val(): "& ( val(qry.bigIntValue1) eq val(qry.bigIntValue2)) );
writeOutput("<br>Varchar Val(): "& ( val(qry.varcharValue1) eq val(qry.varcharValue2)) );
writeOutput("<br>Long.compareTo: "& qry.bigIntValue1[1].compareTo(qry.bigIntValue2[1]));
writeOutput("<br>Varchar.compareTo: "& qry.varcharValue1[1].compareTo(qry.varcharValue2[1]));
writeOutput("<br>Compare(Long, Long) "& compare(qry.bigIntValue1, qry.bigIntValue2));
writeOutput("<br>Compare(Varchar, Varchar) "& compare(qry.varcharValue1, qry.varcharValue2));
Produces these results:
val(qry.bigIntValue1): 1.00900000006E+016
val(qry.bigIntValue21): 1.00900000006E+016
BigInt Val(): YES
Varchar Val(): YES
Long.compareTo: 1
Varchar.compareTo: 2
Compare(Long, Long): 1
Compare(Varchar, Varchar): 1
As expected, the val() comparison returns the wrong answer, because the function implicitly converts the large numbers to an approximate type. Once converted, these approximate values are considered equal.
All of the other comparisons indicate the values are NOT equal. While the examples use different functions, they all have one thing in common: they all return 0 when the values are considered equal. Anything else indicates the values are different. Since zero (0) is treated as false in CF, be sure you are using the correct expression to test for equality and differences.
Long.compareTo() - (Data type used to represent BigInt in CF) the value 0 if this Long is equal to the argument Long; a value less than 0 if this Long is numerically less than the argument Long; and a value greater than 0 if this Long is numerically greater than the argument Long (signed comparison)."
String.compareTo() - the value 0 if the argument string is equal to this string; a value less than 0 if this string is lexicographically less than the string argument; and a value greater than 0 if this string is lexicographically greater than the string argument.
Compare(string1, string2) - "...Performs a case sensitive comparison of two strings.? Returns -1 (less than), 0 (equal) or 1 (greater than)

I have another simple solution for this. I think it may help you.
<cfset x = 10090000000557765/>
<cfset y = 10090000000557763/>
<cfset isZero = PrecisionEvaluate( x-y )/>
<cfif isZero EQ 0>
x and y are equal
<cfelse>
x and y are not equal
</cfif>
As values exceeds its data type (like int, longInt etc.) limit then it become problematic to perform arithmetical operations. So I have used PrecisionEvaluate().

Related

In Ocaml, when comparing strings (which contain numbers), how are the boolean values evaluated?

The string comparison "3" <= "4";; evaluates as "bool = true"
Here 3 is less than 4 so this makes sense.
This string comparison "3" <= "9";;evaluates as "bool = true"
3 is less than 9 so this makes sense.
Why then does the string comparison "3" <= "10";; evaluate to "bool = false"?
Does it have to do with the length of strings, or perhaps their ASCII values?
Thank you for your time.
It's a normal lexicographical order.
"3" > "10" for the same reason that "d" > "ba".
The first character of string A is compared to the first character of string B. If they're different, you're done.
If they're the same, then the second character of string A is compared to the second character of string B. If they're different, you're done.
If they're the same, then the third character ...
This continues until either both strings run out of characters at the same time (then they're equal) or one of the strings runs out first (that string is "less than" the other one).

c++ std::string '==' operator and Compare method is return Not equal value to equal string

motion->bone_frames[0].name == model->bones[0].bone_name//it return 0 . it should be 1
motion->bone_frames[0].name.Compare(model->bones[0].bone_name)//it return 1 . it should be 0
wcscmp(motion->bone_frames[0].name.c_str(), model->bones[0].bone_name.c_str()) //it return 0 it should be 0 correct
I cant understand std::string compare functions why have different result to wcscmp.
Can i know why these results are different?
Is it cause of different is length?
Because they are not equal. Check the size of your strings in the image that you've attached. In the first there are '\0' at the end of the string, that are characters as well.
wcscmp stops comparing when it hits L'\0'. A std::wstring will consider the size() of the strings.
The string == and compare will return "different" results as the first returns true and the second returns 0 for equal strings. See Differences between C++ string == and compare()?
The standard operator== returns lhs.compare(rhs) == 0.

Sql, Compged, Min and blanks

I'm comparing 4 strings using compged in sql here is an extract:
MIN(compged(a.string1,b.string1),
compged(a.string1,b.string2),
compged(a.string2,b.string1),
compged(a.string2,b.string2)) < 200
Unfortunately there are times that a string from set a and a string from set b is blank/empty, this means compged resolves to 0 and the min found is 0. Is there a way to modify so that comparing two blank strings gives a value greater than 200 or something?
Thanks in advance
You can calculate new variables to handle that situation (both compared variables are blank) and use them inside the MIN() function:
case
when (missing(a.string1) and missing(b.string1)) then 300
else compged(a.string1,b.string1)
end as compged_11,
/* do the same for combinations 12, 21 and 22 */
MIN(calculated compged_11,
calculated compged_12,
calculated compged_21,
calculated compged_22) < 200
The quick and dirty option is to wrap each string with a different 200char string in case the string is null or the length is 0 (as empty strings aren't always referenced as NULL)
So a.string1 = 200*'Z', b.string1 = 200*'X'.....
Or better even, to wrap each call with checks so if a.string1 is null or is empty, then return the length of the other string. And if both are empty, then return 1000 so the record is removed by the where clause.
You can also add a prefix - 'A' to all strings. This will ensure tht there are no empty strings, and will not change the distance. But you still need to weed out cases where both strings are empty.

Regual expression strange behavior

QRegExp regexpsplineedit("[a-zA-Z0-9\\_\\[\\]\\(\\)]{20}");
qlineedit->setValidator(new QRegExpValidator(regexpsplineedit,this));
This work.
And this not :
if(clipboardtext.contains(QRegExp("[a-zA-Z0-9\\_\\[\\]\\(\\)]{20}")))
But this yes :
if(clipboardtext.contains(QRegExp("[a-zA-Z0-9\\_\\[\\]\\(\\)]")) && clipboardtext.length() <= 20)
Why this happens with same text for input?
Are you validating the length of the string is less than or equal to 20? Or that at least 1 char from that class exists and the total length is less than or equal to 20? That is 2 separate validation steps. Otherwise, its just ^[chars]{1,20}$
– sln

Largest digit in a string using isdigit for python 3

I'm trying to find the largest digit in a string of texts with alpha and numeric characters.
The source works in Python v2 but not in Python v3. When I run the module in Python 3 it returns with an error "TypeError: unorderable types: str() > int()
largestdigit = 0
n = 5000
with open('pg76.txt') as file:
sentence = file.read()
#FIND LARGEST DIGIT FOR SPECIFIED N SIZE
for i in range(0,n):
if sentence[i].isdigit():
if sentence[i] > largestdigit:
largestdigit = sentence[i]
#OUTPUT
print ("loaded \"pg76.txt\" of length", len(sentence))
print ("n =", n)
if largestdigit == 0:
print ("largest digit = None")
else:
print ("Largest digit =", largestdigit )
The TypeError that you see was part of a deliberate change. Python3 offers more complex and precise comparison operators and, as a result, the older "unnatural" comparisons have been removed. This is documented as part of What's New for Python3:
Python 3.0 has simplified the rules for ordering comparisons:
The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.
Thus, expressions like 1 < '', 0 > None or len <= len are no longer
valid, and e.g. None < None raises TypeError instead of returning
False. A corollary is that sorting a heterogeneous list no longer
makes sense – all the elements must be comparable to each other. Note
that this does not apply to the == and != operators: objects of
different incomparable types always compare unequal to each other.
So, you need to either stick with characters or convert all the digits to integers. If you choose conversion:
if int(sentence[i]) > largestdigit:
largestdigit = int(sentence[i])
In the statement
if sentence[i] > largestdigit:
you are trying to compare a string value with an integer value. Python does not automatically convert a string to an integer, so even though Python 2 doesn't show you an error, the code is not doing what you assume it is.
In Python 2, when you try to compare a string and an integer, the string ALWAYS evaluates to greater than the integer. So, in your code, sentence[i] will ALWAYS be greater than largestdigit, even if you set sentence[i] to '1' and largestinteger to 9.
In Python 3, instead of assuming that strings are always greater than integers, Python throws an error, which is what you are seeing.
You need to manually convert the string to an integer using the int() method. So, that line of code will become:
if int(sentence[i]) > largestdigit:
largestdigit = int(sentence[i])
EDIT: As user falsetru mentioned in the comments, another alternative is to make everything strings, in which case Python will evaluate them based on their ASCII code, and your digits comparison will work correctly. In this case, all you need to do is modify the line where you initialize largestdigit:
largestdigit = '0'
and also the comparision you make in the OUTPUT section:
if largestdigit == '0':