我有这段剧本:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @arr = (
{
name => 'foo',
value => 123,
},
{
name => 'bar',
value => 'nan',
},
{
name => 'foobar',
value => 456,
},
);
@arr = sort {$a->{value} <=> $b->{value} } @arr;
print Dumper(\@arr);
我在Windows XP / Strawberry Perl 5.10.1
下没有任何问题为i386-linux-thread-multi构建的Linux 2.6.12-1 i386 / Perl v5.8.5,
但是在针对x86_64-linux-thread-multi构建的Linux 2.6.18-53 / Perl v5.8.8下,我收到了错误消息:
Sort subroutine didn't return a numeric value at testsort.pl line 21.
出了什么问题,我该如何解决?
答案 0 :(得分:6)
在某些版本中,对于<=>
比较,'nan'被强制为0,排序成功。在其他版本中,nan
被视为“非数字”,<=>
的返回值未定义。
为了获得最大的可移植性,请测试一个值是否为好的数字:
(来自How do I create or test for NaN or infinity in Perl?的isnan
子程序):
sub isnan { ! defined( $_[0] <=> 9**9**9 ) }
@arr = sort { isnan($a->{value}) ? 0 : $a->{value}
<=>
isnan($b->{value}) ? 0 : $b->{value} } @arr;
答案 1 :(得分:4)
mobrule的解决方案:
sub isnan { ! defined( $_[0] <=> 9**9**9 ) }
@arr = sort { isnan($a->{value}) ? 0 : $a->{value}
<=>
isnan($b->{value}) ? 0 : $b->{value} } @arr;
Perldoc的解决方案:
@result = sort { $a <=> $b } grep { $_ == $_ } @input;
NaN
0
值,该值应将其推送到列表顶部。NaN != NaN
来消除输入列表中的任何NaN
。正如mobrule所述,这是由于构建之间NaN
的比较造成的。