为什么当值相同时,我的值比较返回false?

问题描述:

我有一个perl脚本,可以将Excel XLS文件中的数据加载到数据库中。首先,它检查数据库中是否存在来自文件的值的日期时间。如果确实如此,它会检查文件中的值是否与数据库中的值相同。如果它们相同,则跳过该值。如果它们不同,数据库中的值会更新。为什么当值相同时,我的值比较返回false?

,做比较的代码是:

if($dbVal != $fileVal) { 
    &UpdateData($id, $dt, $fileVal); 
} 

的问题是,有时,即使两个值“看”相同,比较确定他们不是并执行更新子。以下是调试日志的摘录。对于文件中的每个值,它都会输出db值和文件值。如果更新子被执行,“更新......”两行文字:

dbVal = '68800812'; file val = '68800812' 
dbVal = '66649164'; file val = '66649164' 
Updating: 41248 : 01/01/2011 07:00 : 66649164 
dbVal = '64975681'; file val = '64975681' 
dbVal = '64037179'; file val = '64037179' 
dbVal = '64095165'; file val = '64095165' 
dbVal = '64917078'; file val = '64917078' 
dbVal = '66584188'; file val = '66584188' 
Updating: 41248 : 01/01/2011 12:00 : 66584188 

所以在上面的片段中,有两个实例,其中分贝VAL和文件VAL看起来是一样的,但更新子无论如何都被执行了,这意味着当它看起来应该是错误的时候,比较返回true。

有什么想法/想法?

戴夫

+3

查看'Devel :: Peek :: Dump'和'sprintf'%.100f''的值。 – daxim 2012-03-20 15:50:40

+0

使用'printf'查看值显示出不同。看起来像“66649164”的值实际上是文件中的“66649164.000000007450580596923828125”。 >:\ 添加此作为答案,我会接受它。 – DaveKub 2012-03-20 18:01:32

杰韦利::皮克揭示了标量类型NV(浮动)而不是预期IV(整数)。 sprintf显示不精确,见Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)?。当在字符串上下文中简单地打印或使用其他字符时,该数字被强制转换为具有16位尾数的表示(如果使用指数表示,则为20-21)。

在进行比较之前明确地舍入数字,sprintfMath::Round是合适的。

也许你的价值观被当作字符串和一个FO两个必须在开始/结束的额外空间。

尝试这种情况:

if($dbVal - $fileVal != 0) { 
    &UpdateData($id, $dt, $fileVal); 
} 
+0

你没有测试这个理论,是吗?将字符串转换为数字时,Perl将忽略空格。 – TLP 2012-03-20 16:51:47

+0

另外,当我将值打印到调试日志时,我用单引号括住变量名称以显示任何前导/尾随空格。这是我几年前的习惯。 – DaveKub 2012-03-20 17:19:12