2012-03-20 12 views
0

Excel XLSファイルからデータベースにデータを読み込むperlスクリプトがあります。最初に、ファイルからの値のdatetimeがデータベースにすでに存在するかどうかを確認します。存在する場合は、ファイルの値がデータベース内の値と同じかどうかを確認します。値が同じであれば、値はスキップされます。それらが異なる場合は、データベースの値が更新されます。比較を行う値が同じ場合、値の比較が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 

したがって、上記のスニペットでは、2デシベルのヴァルとファイルvalは同じように見えるが、インスタンスの更新サブがありましたとにかく実行されました。つまり、比較がfalseになったはずのように見えるときにtrueが返されます。

ご意見/ご提案はありますか?デイブ

+3

'Devel :: Peek :: Dump'と' sprintf '%.100f''で値を見てください。 – daxim

+0

'printf'を使って値を見るとその違いが分かりました。 '66649164'のような値は、実際には '66649164.000000007450580596923828125'でした。 >:\ これを回答として追加し、私はそれを受け入れます。 – DaveKub

答えて

3

のDevel :: PEEKはスカラ型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が適切です。

0

はたぶんあなたの値は文字列のように扱われ、2つのfoの1は最初/最後に余分なスペースを持っています。

これを試してみてください:

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

あなたはその理論をテストしていませんでしたか?文字列を数値に変換するとき、Perlは空白を無視します。 – TLP

+0

また、値をデバッグログに出力するときに、先行/後続スペースを表示するために変数名を一重引用符で囲みます。それは私が数年前に得た習慣です。 – DaveKub

関連する問題