程式網址: http://codepad.org/n9aVPfa5
從 Ouput 可看出 fp_equal_method3 比較 robust
程式碼:
##################################################
# 以下舉例 32bits floating-point 比較(等於) 的問題
$float1 = 3.0e+38;
$float2 = 1.06;
#######################################################################
# pack 成 32bits floating-point 後再 unpack(i.e. double->float->double)
#
# ref. http://www-cgi.cs.cmu.edu/afs/cs/user/rgs/mosaic/pl-exp-conv.html
$new_float1 = unpack('f',pack('f',$float1));
$new_float2 = unpack('f',pack('f',$float2));
#################################
# 直接用 == operator 比較是否等於
&fp_equal_method1($float1,$new_float1);
&fp_equal_method1($float2,$new_float2);
#######################################
# 指定精確度(significant)後比較是否等於
&fp_equal_method2($float1,$new_float1);
&fp_equal_method2($float2,$new_float2);
############################
# 重新 pack 後再比較是否等於
&fp_equal_method3($float1,$new_float1);
&fp_equal_method3($float2,$new_float2);
####################
# 直接用 == operator
sub fp_equal_method1{
my $v1 = shift;
my $v2 = shift;
if($v1 == $v2){
print "fp_equal_method1: $v1 equal $v2\n";
}
}
##############
# Knuth method
#
# ref. http://perldoc.perl.org/perlop.html (Floating-point Arithmetic)
sub fp_equal_method2{
my $v1 = shift;
my $v2 = shift;
if(sprintf("%.8g",$v1) eq sprintf("%.8g",$v2)){
print "fp_equal_method2: $v1 equal $v2\n";
}
}
######################
# re-pack then compare
sub fp_equal_method3{
my $v1 = shift;
my $v2 = shift;
if(pack('f',$v1) eq pack('f',$v2)){
print "fp_equal_method3: $v1 equal $v2\n";
}
}