在更新一些遗留 Perl 代码的过程中,我遇到了 C 样式for
循环过早终止的情况。
问题
可以按如下方式重新创建这种情况(我在 Linux 和 Windows 上的结果相同):
$ perl
for($i = 0.8; $i <= 2.5; $i+=0.1){
print $i, "\n";
}
__END__
0.8
0.9
1
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2
2.1
2.2
2.3
2.4
2.5 明显不存在;它应该已经通过了$i <= 2.5
条件。
修复
意识到这可能是由于浮点表示,如 中所述perldoc perlfaq4
,我更新了条件:
$ perl
for($i = 0.8; sprintf( '%.1f', $i ) <= 2.5; $i += 0.1 ) {
print $i, "\n";
}
__END__
0.8
0.9
1
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2
2.1
2.2
2.3
2.4
2.5 <--- Gotcha !
服务恢复了(或者我是这么认为的)。
验证
我想证明 final$i
确实大于 2.5,所以我将增量包装在一个do
循环中:
$ perl
for($i = 0.8; $i <= 2.5; do { $i += 0.1; print $i, "\n"; } ) {}
__END__
0.9
1
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2
2.1
2.2
2.3
2.4
2.5 <--- Surprise!
测试结果似乎表明浮点表示不是这里的问题。
这里发生了什么?