我看到以下日志消息。通过查看数字,我怀疑timeStampLastSeekPoint
总是一加timeInNanos
。
% grep -E '^java.lang.IllegalArgumentException.*timeStampLastSeekPoint' messages | head -5
java.lang.IllegalArgumentException: timeInNanos=1500629929661000010, timeStampLastSeekPoint=1500629929661000011
java.lang.IllegalArgumentException: timeInNanos=1500629929661000010, timeStampLastSeekPoint=1500629929661000011
java.lang.IllegalArgumentException: timeInNanos=1500629929661000010, timeStampLastSeekPoint=1500629929661000011
java.lang.IllegalArgumentException: timeInNanos=1500630763150000010, timeStampLastSeekPoint=1500630763150000011
java.lang.IllegalArgumentException: timeInNanos=1500630763150000010, timeStampLastSeekPoint=1500630763150000011
为了证实我的怀疑,我用这个perl单线管道来提取数字并显示差异。差异显示全0,这不可能是真的。很明显我需要更高的精度。
% grep -E '^java.lang.IllegalArgumentException.*timeStampLastSeekPoint' messages | \
perl -ne 'if (/timeInNanos=(\d+), timeStampLastSeekPoint=(\d+)/) { printf("%ld %ld %ld\n", $1, $2, $2 - $1) }' | head -5
1500629929661000010 1500629929661000011 0
1500629929661000010 1500629929661000011 0
1500629929661000010 1500629929661000011 0
1500630763150000010 1500630763150000011 0
1500630763150000010 1500630763150000011 0
我用Google搜索,找到bigint
模块,然后尝试了。但是,它仍然无效。
% grep -E '^java.lang.IllegalArgumentException.*timeStampLastSeekPoint' messages | \
perl -Mbigint -ne 'if (/timeInNanos=(\d+), timeStampLastSeekPoint=(\d+)/) { printf("%ld %ld %ld\n", $1, $2, $2 - $1) }' | head -5
1500629929661000010 1500629929661000011 0
1500629929661000010 1500629929661000011 0
1500629929661000010 1500629929661000011 0
1500630763150000010 1500630763150000011 0
1500630763150000010 1500630763150000011 0
经过几次尝试后,我发现只有在将regexp匹配分配给常规变量后才能正常工作。顺便说一句,我现在证实我怀疑差异总是1。
% grep -E '^java.lang.IllegalArgumentException.*timeStampLastSeekPoint' messages | \
perl -Mbigint -ne 'if (/timeInNanos=(\d+), timeStampLastSeekPoint=(\d+)/) { printf("%ld %ld %ld\n", $1, $2, ($b=$2) - ($a=$1)) }' | head -5
1500629929661000010 1500629929661000011 1
1500629929661000010 1500629929661000011 1
1500629929661000010 1500629929661000011 1
1500630763150000010 1500630763150000011 1
1500630763150000010 1500630763150000011 1
现在我找到了解决方法。但是,为什么分配是必要的并不直观。 $2 - $1
不应该工作吗?感觉就像一个bug。或者,有没有解释才能理解这是一种合理的行为? perl版本是v5.14.2。
答案 0 :(得分:0)
您的代码行为在perl 5.16和perl 5.18之间发生了变化。我没有进一步研究,以了解更改是修复还是实现。
$ PATH=/usr/local/ActivePerl-5.16/bin:$PATH
$ grep -E '^java.lang.IllegalArgumentException.*timeStampLastSeekPoint' messages | perl -ne 'if (/timeInNanos=(\d+), timeStampLastSeekPoint=(\d+)/) { printf("%ld %ld %ld\n", $1, $2, $2 - $1) }' | head -5
1500629929661000010 1500629929661000011 0
1500629929661000010 1500629929661000011 0
$ PATH=/usr/local/ActivePerl-5.18/bin:$PATH
$ grep -E '^java.lang.IllegalArgumentException.*timeStampLastSeekPoint' messages | perl -ne 'if (/timeInNanos=(\d+), timeStampLastSeekPoint=(\d+)/) { printf("%ld %ld %ld\n", $1, $2, $2 - $1) }' | head -5
1500629929661000010 1500629929661000011 1
1500629929661000010 1500629929661000011 1
答案 1 :(得分:0)
use bigint;
对您的程序没有影响,因为它只影响数字文字,而您的程序没有。
use bigint;
有效地用Math::BigInt->new("LITERAL")
替换数字文字。这意味着
use bigint;
2
相当于
use Math::BigInt qw( );
Math::BigInt->new("2")
这提出了一个解决方案:
use Math::BigInt qw( );
Math::BigInt->new($2) - Math::BigInt->new($1)
但是由于重载运算符,你可以简单地使用
use Math::BigInt qw( );
Math::BigInt->new($2) - $1
或
use bigint;
0 + $2 - $1
在所有情况下,您希望使用%s
(而非%d
)让M :: BI字符串化数字
而不是将其编号为整数。