diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm index 8a904a97..44940dec 100644 --- a/perl/lib/Data/MessagePack/PP.pm +++ b/perl/lib/Data/MessagePack/PP.pm @@ -22,10 +22,19 @@ BEGIN { if(!eval { pack 'Q', 1 }) { # don't have quad types $unpack_int64_slow = sub { require Math::BigInt; - my $high = Math::BigInt->new( unpack_int32( $_[0], $_[1]) ); - my $low = Math::BigInt->new( unpack_uint32( $_[0], $_[1] + 4) ); + my $high = unpack_uint32( $_[0], $_[1] ); + my $low = unpack_uint32( $_[0], $_[1] + 4); - return +($high << 32 | $low)->bstr; + if($high < 0xF0000000) { # positive + $high = Math::BigInt->new( $high ); + $low = Math::BigInt->new( $low ); + return +($high << 32 | $low)->bstr; + } + else { # negative + $high = Math::BigInt->new( ~$high ); + $low = Math::BigInt->new( ~$low ); + return +( -($high << 32 | $low + 1) )->bstr; + } }; $unpack_uint64_slow = sub { require Math::BigInt; diff --git a/perl/t/data.pl b/perl/t/data.pl index 8ffd25ae..95eac419 100644 --- a/perl/t/data.pl +++ b/perl/t/data.pl @@ -35,4 +35,9 @@ no warnings; # i need this, i need this. 'd3 ff ff ff ff ff ff ff ff' => '-1', # int64_t 'cf ff ff ff ff ff ff ff ff' => '18446744073709551615', # uint64_t + + # int64_t + 'd3 00 00 00 10 00 00 00 00' => '68719476736', + 'd3 00 00 00 10 00 00 00 01' => '68719476737', + 'd3 10 00 00 00 00 00 00 00' => '1152921504606846976', )