Parse::Matroska::Reader: get rid of `bigrat`

It seems that it was causing issues with certain perl setups (such as
the one on issue #549). It also turns out that it was not behaving correctly
(not all constants were being promoted to big nums as they should), so we
use explicit objects to derive the constants.

There were also precedence issues. I wonder if this even worked right to
begin with.

The 'double' path (8-byte floats) is untested, as I couldn't easily find
a file with such a field.

Closes #549.
This commit is contained in:
Diogo Franco (Kovensky) 2014-02-15 19:38:32 -03:00 committed by wm4
parent c4d905b567
commit 6d9d597b10
1 changed files with 20 additions and 17 deletions

View File

@ -132,7 +132,8 @@ sub _bin2int($) {
# creates a floating-point number with the given mantissa and exponent
sub _ldexp {
my ($mantissa, $exponent) = @_;
return $mantissa * Math::BigRat->new(2)**$exponent;
my $r = new Math::BigRat($mantissa);
return $r * Math::BigRat->new(2)**$exponent;
}
# NOTE: the read_* functions are hard to read because they're ports
@ -252,25 +253,27 @@ bytes from the internal filehandle.
Only lengths C<4> and C<8> are supported (C C<float> and C<double>).
=cut
sub read_float {
my ($self, $length) = @_;
my $i = $self->read_uint($length);
my $f;
{
my $b1 = new Math::BigInt 1;
use bigrat try => BIGINT_TRY;
sub read_float {
my ($self, $length) = @_;
my $i = new Math::BigInt $self->read_uint($length)->bstr;
my $f;
# These evil expressions reinterpret an unsigned int as IEEE binary floats
if ($length == 4) {
$f = _ldexp(($i & (1<<23 - 1)) + (1<<23), ($i>>23 & (1<<8 - 1)) - 150);
$f = -$f if $i & (1<<31);
} elsif ($length == 8) {
$f = _ldexp(($i & (1<<52 - 1)) + (1<<52), ($i>>52 & (1<<12 - 1)) - 1075);
$f = -$f if $i & (1<<63);
} else {
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
# These evil expressions reinterpret an unsigned int as IEEE binary floats
if ($length == 4) {
$f = _ldexp(($i & ((1<<23) - 1)) + (1<<23), ($i>>23 & ((1<<8) - 1)) - 150);
$f = -$f if $i & ($b1<<31);
} elsif ($length == 8) {
$f = _ldexp(($i & (($b1<<52) - 1)) + ($b1<<52), ($i>>52 & ((1<<12) - 1)) - 1075);
$f = -$f if $i & ($b1<<63);
} else {
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
}
return $f;
}
return $f;
}
=method read_ebml_id($length)