我有 2 個變數,x,y 和“數字”資料。請注意,這兩者都來自不同的來源(mysql 資料和決議的檔案資料),所以我首先假設它們最終以字串的形式出現。
## this will work fine with any data that I assign manually, so can't reproduce the issue for you here...
## $x sourced from an sql query, $y sourced from a parsed file
warn "test x == y, $x == $y is " . ($x == $y);
warn "test x != y, $x != $y is " . ($x != $y);
warn "test x eq y, $x eq $y is " . ($x eq $y);
warn "test x ne y, $x ne $y is " . ($x ne $y);
warn "unpack x, " . unpack 'H*', $x;
warn "unpack y, " . unpack 'H*', $y;
輸出
test x == y, 14 == 14 is
test x != y, 14 != 14 is 1
test x eq y, 14 eq 14 is 1
test x ne y, 14 ne 14 is
unpack x, 3134
unpack y, 3134
除非我的頭發一天不好,這是可能的。前兩個測驗“看起來”不正確,因為我希望將字串轉換為數字并進行比較。
我可以通過使用“ne”而不是 != 來解決它,但我想嘗試理解,所以我不會在其他地方引入錯誤,因為有些問題我不明白。
注意:如果我事先將 14 或“14”分配給 $y 進行測驗,那么一切都會按我的預期進行。對 $x 做同樣的事情沒有任何區別,所以我認為 $y 有一些“有趣”的地方。如果我分配 $y = $y 0 或類似的東西以確保它是一個數字,那沒有區別。
因此,由于我無法很好地重現該示例,因此我試圖了解可能出了什么問題,以及如何隔離 $y 的“不同”之處或對其進行探討。
編輯:If I Devel::Peek at $x(比較后不變)
SV = PVNV(0xe2de4c0) at 0x101ccad8
REFCNT = 1
FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 14
NV = 14
PV = 0x447ab580 "14"\0
CUR = 2
LEN = 10
If I Devel::Peek at $y
SV = PVNV(0xcf94880) at 0xf039770
REFCNT = 1
FLAGS = (NOK,pIOK,pNOK)
IV = 14
NV = 14
PV = 0
我還注意到:
warn ($x - $y);
output: -1.77635683940025e-15
這表明 choroba 可能是正確的(盡管為什么 $y 需要對數字比較進行字串化,但我可以看到在除錯中添加到字串時可能會發生這種情況,但不是在原始字串中)。不過,我對整個事情有點驚訝,事實上它沒有顯示浮動,或者任何簡單的方法來判斷是否是這種情況。
Edit2: Interestingly, this only happens for the number 14 in the test data, number 12 for example gives the correct result, which again may make sense if there is some rounding happening. I've got around it by $x=int($x 0.5) and $y=int($y 0.5) as that's actually what I want the values to be.
Edit: ikegamis sprintf on $y produces
14.0000000000000017763568394002504646778106689453125
Just out of interest, I traced this all the way back to a XML::LibXML::Reader find_value() call, where the number was originally a 0.14 string and multiplied, so my mistake for not doing some proper data checking in the code.
Shouldn't Devel::Peek show the number as 14.0000000000000017763568394002504646778106689453125 under the hood ?
Edit: Just for those interested, I can manually replicate it now with setting the following, which makes the problem a bit more obvious.
my $x = "0.14";
$x *= 100;
my $y = 14;
uj5u.com熱心網友回復:
my $x = 14.000000000000001;
my $y = 14;
當對一個值進行字串化時,Perl 會根據需要對數字進行四舍五入。
另請參閱 每個計算機科學家應該了解的關于浮點運算的知識
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425567.html
標籤:perl
上一篇:使用XML::Twig更新包含命名空間前綴的xml檔案
下一篇:替換大檔案中參考字串中的換行符
