ColdFusion大数对比

ColdFusion large number comparison

ColdFusion 认为 10090000000557765 = 10090000000557763.

我明白为什么,但我需要知道让 ColdFusion 知道它们不一样的最佳方法。我读到了 Compare() 方法,但 return 也是如此。我将它们转换为字符串并且 return 是真的。

我考虑编写一个自定义函数将字符串分成两部分,分别比较每个部分,然后 return true/false 但这似乎很愚蠢。

我试过以下方法:

Val(a) EQ Val(b)
ToString(a) EQ ToString(b)
a.compareTo(b)

澄清一下。我正在使用我无法控制的使用 bigint 的数据库。我很早就了解到 Javascript 无法处理这些,因此我将模型中的所有 bigint 字段都转换为 varchar。但是,现在 CF 在比较字符串时遇到问题,我似乎无法将它们转换回数字。

我刚刚做的例子:

<cfif '10090000000557765' EQ '10090000000557763'>
True
<cfelse>
False
</cfif>

http://cflive.net/ 上 return 为真。看我的笔记。在数据库中,它们是 bigint。取出它们时我不得不将它们转换为 VarChar,因为 Javascript 无法处理 bigint 但它可以很好地处理字符串。

简短回答: 为了不忽视显而易见的 java 方法,例如 Long.compareTo() return -10,或 1。确保您使用正确的表达式来测试相等性。当值相等时,结果将为 0。 (零 (0) 在 CF 中计算为 false)。

更长的答案: 如何存储、检索值,特别是如何 evaluated 在这里非常相关。您提到的所有方法在 CF11 下对我来说都很好(val 除外,原因很明显)。这表明您的代码或环境有所不同。

例如,使用 CF11 和 SQL 服务器:

CREATE TABLE test
(
    bigIntValue1 BIGINT
    , bigIntValue2 BIGINT
    , varcharValue1 VARCHAR(50)
    , varcharValue2 VARCHAR(50)
)

以下测试代码:

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

产生这些结果:

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 

正如预期的那样,val() 比较 return 是错误的答案,因为该函数隐式地将大数转换为 近似值 类型。一旦转换,这些近似值被认为是相等的。

所有其他比较表明值不相等。虽然这些示例使用不同的函数,但它们都有一个共同点:当值被认为相等时,它们都是 return 0。任何其他表示值 不同 。由于零 (0) 在 CF 中被视为 false,因此请确保您使用正确的表达式来测试相等性和差异性。

  • Long.compareTo() - (CF中用于​​表示BigInt的数据类型)如果此Long等于参数Long,则值为0;如果此 Long 在数值上小于参数 Long,则为小于 0 的值;如果此 Long 在数值上大于参数 Long(有符号比较),则为大于 0 的值。"
  • String.compareTo() - 如果参数字符串等于此字符串,则值为 0;如果此字符串按字典顺序小于字符串参数,则该值小于 0;如果此字符串在字典序上大于字符串参数,则为大于 0 的值。

  • Compare(string1, string2) - "...对两个字符串进行区分大小写的比较。? Returns -1(小于), 0(等于)或 1(大于)

我有另一个简单的解决方案。我觉得可能对你有帮助。

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

当值超出其数据类型(如 int、longInt 等)限制时,执行算术运算就会出现问题。所以我用了PrecisionEvaluate().