RosettaCodeData/Task/Approximate-equality/Perl/approximate-equality.pl

34 lines
967 B
Perl

use strict;
use warnings;
sub is_close {
my($a,$b,$eps) = @_;
$eps //= 15;
my $epse = $eps;
$epse++ if sprintf("%.${eps}f",$a) =~ /\./;
$epse++ if sprintf("%.${eps}f",$a) =~ /\-/;
my $afmt = substr((sprintf "%.${eps}f", $a), 0, $epse);
my $bfmt = substr((sprintf "%.${eps}f", $b), 0, $epse);
printf "%-5s %s ≅ %s\n", ($afmt eq $bfmt ? 'True' : 'False'), $afmt, $bfmt;
}
for (
[100000000000000.01, 100000000000000.011],
[100.01, 100.011],
[10000000000000.001 / 10000.0, 1000000000.0000001000],
[0.001, 0.0010000001],
[0.000000000000000000000101, 0.0],
[sqrt(2) * sqrt(2), 2.0],
[-sqrt(2) * sqrt(2), -2.0],
[100000000000000003.0, 100000000000000004.0],
[3.14159265358979323846, 3.14159265358979324]
) {
my($a,$b) = @$_;
is_close($a,$b);
}
print "\nTolerance may be adjusted.\n";
my $real_pi = 2 * atan2(1, 0);
my $roman_pi = 22/7;
is_close($real_pi,$roman_pi,$_) for <10 3>;