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

Storable Alters Floating Point Number? #15019

Closed
p5pRT opened this issue Oct 30, 2015 · 7 comments
Closed

Storable Alters Floating Point Number? #15019

p5pRT opened this issue Oct 30, 2015 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 30, 2015

Migrated from rt.perl.org#126502 (status was 'resolved')

Searchable as RT126502$

@p5pRT
Copy link
Author

p5pRT commented Oct 30, 2015

From eric@vertical-approach.com

Hi,

I don't know if this is an issue with Storable or with Perl itself, but when I compare two identical floating points together, they compare correctly. However, when I freeze() and thaw() them, they do not.

I am familiar with the dynamics of how floating points are stored, so that's not the issue. The issue is that Storable slightly alters an SvPVNV in a way that it doesn't compare like it used to. Here's the code (this is on Perl 5.18 and Storable 2.51)​:

  use 5.018001;
  use warnings;
  use Math​::Round qw(nearest);
  use Storable qw(freeze thaw);

  my $a = nearest(.01,-656.8);
  my $b = nearest(.01,-656.8);
  if ($a eq 'qwer') {} # this upgrades $a to an SvPVNV
  say '' . ($a == $b ? 'EQUAL' : 'NOT EQUAL');

  my $c = thaw(freeze(\$a)); # here Storable alters the SvPVNV so that it compares incorrectly
  my $d = thaw(freeze(\$b));
  say '' . ($c == $d ? 'EQUAL' : 'NOT EQUAL');

OUTPUT​:

  EQUAL
  NOT EQUAL

(NOTE​: I know that '==' is unreliable for comparing floating point numbers, and that doing a nearest(.01,$a) eq nearest(.01,$b) is a more reliable way to solve this. Regardless, I still think this might be a bug folks would want addressed?)

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2015

From zefram@fysh.org

masterchiefaragorn wrote​:

my $c = thaw(freeze(\$a)); # here Storable alters the SvPVNV so that it compares incorrectly
my $d = thaw(freeze(\$b));
say '' . ($c == $d ? 'EQUAL' : 'NOT EQUAL');

$c isn't the PVNV that you're interested in; it's a *reference to* a PVNV.
It's a clone of \$a, not of $a. The numbers you want to compare at the
end are $$c and $$d, and they compare ==.

(NOTE​: I know that '==' is unreliable for comparing floating point numbers,

== is a perfectly good comparison operator. It's + and * and all those
other arithmetic operators that misbehave on floating point numbers.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2015

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2015

From eric@vertical-approach.com

So sorry...I mis-typed those last lines when submitting my simplified reproduction of this issue. Try out this snippet of code. It yields 'EQUAL' and then 'NOT EQUAL' on my Linux machine​:

  use 5.018001;
  use warnings;
  use Math​::Round qw(nearest);
  use Storable qw(freeze thaw);

  my $a = nearest(.01,-656.8);
  my $b = nearest(.01,-656.8);
  if ($a eq 'qwer') {} # this upgrades $a to an SvPVNV
  say '' . ($a == $b ? 'EQUAL' : 'NOT EQUAL');

  my $c = thaw(freeze(\$a)); # here Storable alters the SvPVNV so that it compares incorrectly
  my $d = thaw(freeze(\$b));
  say '' . ($$c == $$d ? 'EQUAL' : 'NOT EQUAL');

@p5pRT
Copy link
Author

p5pRT commented Nov 2, 2015

From @tonycoz

On Sun Nov 01 12​:33​:21 2015, eric@​vertical-approach.com wrote​:

So sorry...I mis-typed those last lines when submitting my simplified
reproduction of this issue. Try out this snippet of code. It yields
'EQUAL' and then 'NOT EQUAL' on my Linux machine​:

use 5.018001;
use warnings;
use Math​::Round qw(nearest);
use Storable qw(freeze thaw);

my $a = nearest(.01,-656.8);
my $b = nearest(.01,-656.8);
if ($a eq 'qwer') {} # this upgrades $a to an SvPVNV
say '' . ($a == $b ? 'EQUAL' : 'NOT EQUAL');

my $c = thaw(freeze(\$a)); # here Storable alters the SvPVNV so that
it compares incorrectly
my $d = thaw(freeze(\$b));
say '' . ($$c == $$d ? 'EQUAL' : 'NOT EQUAL');

This produces

EQUAL
EQUAL

on 5.20, but not because of a change in Storable, the fix was​:

commit b127e37
Author​: Karl Williamson <public@​khwilliamson.com>
Date​: Mon May 13 07​:35​:35 2013 -0600

  PATCH​: [perl #108378] [perl #115800]
 
  This patch solves two tickets. Both are a result of the stringification
  of a floating number being sticky, so that the character representing
  the decimal point may be from an old locale. The patch solves this by
  not retaining the stringification of NVs.

Tony

@p5pRT
Copy link
Author

p5pRT commented Nov 4, 2015

From eric@vertical-approach.com

Thanks for letting me know that's been fixed!! I've upgraded to 5.22.0, and I now also get​:

  EQUAL
  EQUAL

Thanks. This ticket can be closed.

@p5pRT
Copy link
Author

p5pRT commented Nov 6, 2015

@iabyn - Status changed from 'open' to 'resolved'

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

1 participant