# [sf-perl] Comparing structures, ignoring floating point roundoff differences

Garth Webb garth at perijove.com
Mon Nov 21 23:19:23 PST 2005

```How about:

use strict;

use constant TOLERANCE => 0.01;

sub is_equal {
my (\$v1, \$v2) = @_;

return unless ref \$v1 eq ref \$v2;

if (ref \$v1 eq 'HASH') {
return hash_eq(\$v1, \$v2);
} elsif (ref \$v2 eq 'ARRAY') {
return array_eq(\$v1, \$v2);
} elsif (not ref \$v1) {
return scalar_eq(\$v1, \$v2);
} else {
return;
}
}

sub hash_eq {
my (\$h1, \$h2) = @_;

foreach my \$k (keys %\$h1) {
return unless is_equal(\$h1->{\$k}, \$h2->{\$k});
}

return 1;
}

sub array_eq {
my (\$a1, \$a2) = @_;

foreach my \$i (0..\$#\$a1) {
return unless is_equal(\$a1->[\$i], \$a2->[\$i]);
}

return 1;
}

sub scalar_eq {
my (\$s1, \$s2) = @_;

return \$s1 =~ /[0-9\.]+/ ? abs(\$s1 - \$s2) < TOLERANCE : \$s1 eq \$s2;
}

On Mon, 2005-11-21 at 11:35 -0800, Joseph Brenner wrote:
> I've got a problem where I need to compare structures that have
> floating point numbers stashed in them.  I want to test the
> structures for identity (ala is_deeply from Test::More), but
> ignore tiny differences in the floating point numbers.
>
> This seems like something that ought to be a solved problem by
> now, but I'm having trouble finding it.  I had some hopes for
> Test::Deep, which at least has a "num" comparison operation where
> you can set a tolerance to ignore, but it looks to me like that's
> only for comparing a computed value to an expected constant
> value: I need to compare computed values that are expected to
> match each other.
>
> Does that ring any bells with anyone?
> _______________________________________________
> SanFrancisco-pm mailing list
> SanFrancisco-pm at pm.org
> http://mail.pm.org/mailman/listinfo/sanfrancisco-pm

```