On Tue, 26 Aug 2003, Jonathan Finger wrote:

> I believe the following will do the packed decimal to integer conversion (It 
> is based on code
> I wrote in a differrent language). Since I currently do not have access to 
> files containing
> packled decimal my testing has been somewhat limited). The code is not 
> blazingly fast
> but I hope it is correct.  Perhaps an optimized version warrants a CPAN 
> module since.
> 
> Jonathan Finger
> 
> sub convert_pack_decimal_to_int
> {
>    my $input = shift;
>    my $output = "";
>    if (length($input))
>      {
>        my $byte = ord(substr($input, -1, 1));
>        my $sign = 1;
>        if ($byte % 16 == 13)
>           {
>           $sign = -1;
>           }
>        substr($input, -1, 1) = chr(int($byte/16) * 16);
>        while (length($input))
>        {
>          my $byte = ord($input);
>            my $high = int($byte/16);
>            my $low = $byte % 16;
>            if (($high !~ /^\d$/) || ($low !~ /^\d$/))
>              {
>              die "Not valid packed data";
>            }
>          substr($input, 0, 1) = "";
>          $output .= "$high$low";
>        }
>        substr($output, -1, 1) = "";
>        $output *= $sign;
>      }
>    return($output);
> }

Do you have a pointer to the spec of the packed decimal?  It seems that
you might want this:

  sub foo {
      my $input = shift;
                                                                                
      if (my ($val, $sign) = unpack('H*', $input) =~ /^(\d*)(.)$/) {
          return ($val + 0) * ($sign eq 'd' ? -1 : 1);
      }
      else {
          die "Not valid packed data";
      }
  }

Having tested it with theis additional code:

$x = chr( 1 * 16 + 2 ) . chr( 3 * 16 + 4 ) . chr( 5 * 16 + 13 );    # -12345

print "foo = ", foo($x), "\n";
print "convert_pack_decimal_to_int = ", convert_pack_decimal_to_int($x), "\n";

timethese(
    1000000,
    {
        'foo'                         => sub { foo($x) },
        'convert_pack_decimal_to_int' =>
          sub { convert_pack_decimal_to_int($x) },
    }
);


[EMAIL PROTECTED] tmp]$ perl -T try.pl
foo = -12345
convert_pack_decimal_to_int = -12345
Benchmark: timing 1000000 iterations of convert_pack_decimal_to_int, foo...
convert_pack_decimal_to_int: 17 wallclock secs (16.26 usr +  0.00 sys = 16.26 CPU) @ 
61500.62/s (n=1000000)
       foo:  6 wallclock secs ( 4.95 usr +  0.00 sys =  4.95 CPU) @ 
202020.20/s(n=1000000)

Clearly this needs more testing, and I need breakfast.

Hope this helps (and isn't wildly wrong :-)

Mike

-- 
[EMAIL PROTECTED]                    |           The "`Stok' disclaimers" apply.
http://www.stok.co.uk/~mike/       | GPG PGP Key      1024D/059913DA 
[EMAIL PROTECTED]                  | Fingerprint      0570 71CD 6790 7C28 3D60
http://www.exegenix.com/           |                  75D2 9EC4 C1C0 0599 13DA


_______________________________________________
Boston-pm mailing list
[EMAIL PROTECTED]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to