[ create a new paste ] login | about

Link: http://codepad.org/3UTfradi    [ raw code | output | fork ]

Perl, pasted on Jul 12:
##################################################
# 以下舉例 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";
   }
   else{
      print "fp_equal_method1: $v1 not 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";
   }
   else{
      print "fp_equal_method2: $v1 not 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";
   }
   else{
      print "fp_equal_method3: $v1 not equal $v2\n";
   }
   
}


Output:
1
2
3
4
5
6
fp_equal_method1: 3e+38 not equal 3.00000000549776e+38
fp_equal_method1: 1.06 not equal 1.05999994277954
fp_equal_method2: 3e+38 equal 3.00000000549776e+38
fp_equal_method2: 1.06 not equal 1.05999994277954
fp_equal_method3: 3e+38 equal 3.00000000549776e+38
fp_equal_method3: 1.06 equal 1.05999994277954


Create a new paste based on this one


Comments: