Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Interchange: users

Vend::Util::round_to_frac_digits() precision issue

 

 

Interchange users RSS feed   Index | Next | Previous | View Threaded


wiggins at danconia

Sep 2, 2009, 7:19 AM

Post #1 of 2 (650 views)
Permalink
Vend::Util::round_to_frac_digits() precision issue

I've been messing with the oft seen issue of rounding floats in Perl and
noticed that the round_to_frac_digits() method can't handle
"exponentized" (word?) numbers. Basically it just returns the original
because the regex can't handle the number. The attached patch handles
this case by assuming we are close enough to zero to not care (I
suppose for correctness it should examine $digits to make that
judgement) and returns 0 in this case. A number recognized as before
should be handled as before. Anything else I've added a warning for, but
otherwise handle as before (aka returning what was given).

I don't know if this is a consequence of my Perl build, 64 bit OS, a
newer Perl version, or what. I'll leave that to the experts to suss out.

Example failure numbers:

-2.13370987545147e-16
-1.4210854715202e-14

Thoughts?


From 1a133ec7a0119fdfee9702fb1a8f07a6b7542185 Mon Sep 17 00:00:00 2001
From: Brian J. Miller <brian [at] endpoint>
Date: Wed, 2 Sep 2009 07:59:25 -0600
Subject: [PATCH] Expand range of round_to_frac_digits to handle
exponentized numbers

---
lib/Vend/Util.pm | 20 +++++++++++++++-----
1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/lib/Vend/Util.pm b/lib/Vend/Util.pm
index 8356b84..5be6b5a 100644
--- a/lib/Vend/Util.pm
+++ b/lib/Vend/Util.pm
@@ -269,12 +269,22 @@ sub round_to_frac_digits {
else {
$digits = 2;
}
- my @frac;
- $num =~ /^(-?)(\d*)(?:\.(\d+))?$/
- or return $num;
+ if ($num =~ /^(-?)(\d*)(?:\.(\d+)(?:e-(\d+)))?$/) {
+ # this number sufficiently close to zero for our purposes
+ return 0;
+ }
+ elsif ($num =~ /^(-?)(\d*)(?:\.(\d+))?$/) {
+ # no op
+ }
+ else {
+ warn "Vend::Util::round_to_frac_digits: invalid number
($num)\n";
+ return $num;
+ }
+
my $sign = $1 || '';
- my $int = $2;
- @frac = split(m{}, ($3 || 0));
+ my $int = $2;
+ my @frac = split(m{}, ($3 || 0));
+
local($^W) = 0;
my $frac = join "", @frac[0 .. $digits - 1];
if($frac[$digits] > 4) {
--
1.5.6.3

--
Brian J. Miller
End Point Corp.
http://www.endpoint.com/
brian [at] endpoint

_______________________________________________
interchange-users mailing list
interchange-users [at] icdevgroup
http://www.icdevgroup.org/mailman/listinfo/interchange-users


brian at endpoint

Sep 2, 2009, 7:15 AM

Post #2 of 2 (588 views)
Permalink
Vend::Util::round_to_frac_digits() precision issue [In reply to]

I've been messing with the oft seen issue of rounding floats in Perl and
noticed that the round_to_frac_digits() method can't handle
"exponentized" (word?) numbers. Basically it just returns the original
because the regex can't handle the number. The attached patch handles
this case by assuming we are close enough to zero to not care (I
suppose for correctness it should examine $digits to make that
judgement) and returns 0 in this case. A number recognized as before
should be handled as before. Anything else I've added a warning for, but
otherwise handle as before (aka returning what was given).

I don't know if this is a consequence of my Perl build, 64 bit OS, a
newer Perl version, or what. I'll leave that to the experts to suss out.

Example failure numbers:

-2.13370987545147e-16
-1.4210854715202e-14

Thoughts? I can push via Github if that is preferred.



_______________________________________________
interchange-users mailing list
interchange-users [at] icdevgroup
http://www.icdevgroup.org/mailman/listinfo/interchange-users

Interchange users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.