##################################################
# 以下舉例 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";
   }
   
}