Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential issue in casting numbers #32

Open
akotlar opened this issue Feb 9, 2017 · 2 comments
Open

Potential issue in casting numbers #32

akotlar opened this issue Feb 9, 2017 · 2 comments

Comments

@akotlar
Copy link

akotlar commented Feb 9, 2017

I've noticed some odd behavior, which may simply be the way Perl works, but which could be useful for msgpack-perl to take into account.

Also, once again I would ask that we have some handling for lower-precision floats. It doesn't matter that Perl doesn't separate a double from a float, what matters is how much space the msgpack representation takes. Spending 9 bytes for 1.0 is a waste.

use Data::MessagePack;
use Test::More;
use Scalar::Util qw/looks_like_number/;

sub toNumber {
  if (!looks_like_number($_[0])) {
    return $_[0];
  }

  return $_[0] + 0;
}

my $mp = Data::MessagePack->new();
$mp->prefer_integer();

my $numThatShouldBeInt = "-1.000000";

$converted = toNumber($numThatShouldBeInt);

$packed = $mp->pack($converted);
ok(length($packed) == 1, "Perl does something bizarre when returning numbers from subs");

# Something is very weird
$packed = $mp->pack($numThatShouldBeInt+ 0);
ok(length($packed) == 9, "The string $numThatShouldBeInt takes 9 bytes in msgpack when cast to number, as expected");

# Note that this doesn't occur with a positive number
$packed = $mp->pack("1.000000" + 0);
ok(length($packed) == 9, "The string 1.000000 takes 9 bytes in msgpack when cast to number, as expected");


$packed = $mp->pack(CORE::int($numThatShouldBeInt));
ok(length($packed) == 1, "The string $numThatShouldBeInt takes 1 bytes when cast as int, as expected");
@syohex
Copy link
Collaborator

syohex commented Feb 10, 2017

Perl treats -1.0 as double(NV means double as below), so it is packaged as float64 whose packed size is 9 byte.

% perl -MDevel::Peek -e 'my $i = "-1.000000" + 0; Dump $i'  
SV = NV(0x7fb52a02d718) at 0x7fb52a02d730
  REFCNT = 1
  FLAGS = (NOK,pNOK)
  NV = -1

@akotlar
Copy link
Author

akotlar commented Feb 11, 2017

What is interesting is that this does not seem to be the case if you pass "-1.000" + 0 to pack() (length($packed) == 1). Returning "-1.000" + 0 from a sub, and passing that to pack() indeed results in 9 bytes.

It could be useful for prefer_integer() to also check whether a double can be stored as an int, possibly with an optional flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants