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