develooper Front page | perl.perl5.porters | Postings from March 2020

printf('%d') under -D uselongdouble thinks that 0.001 * 1_000 == 0

Thread Next
From:
Sam Kington
Date:
March 3, 2020 13:44
Subject:
printf('%d') under -D uselongdouble thinks that 0.001 * 1_000 == 0
Message ID:
9AAC071D-6CAA-44EF-93DB-444F85CA6267@illuminated.co.uk
Hi,

perl 5.30.1 compiled using -D uselongdouble thinks that 0.001 * 1_000 == 0:

sam@chimera:timer-milestones$ perlbrew switch perl-5.30.1
sam@chimera:timer-milestones$ perl -e 'printf("%3d\n", 0.001 * 1_000)'
  1
sam@chimera:timer-milestones$ perlbrew switch perl-5.30.1-ld
sam@chimera:timer-milestones$ perl -e 'printf("%3d\n", 0.001 * 1_000)'
  0

If I understand what’s going on correctly, when that value is copied into a Perl variable, it has IV = 1, NV = 1, PV = 0. After printf, the default 5.30.1 sets IOK and pIOK; 5.30.1 compile with -D uselongdouble only sets pIOD, and set IV = 0.

I managed to isolate it to this.

sam@chimera:timer-milestones$ cat precision-weirdness.pl 
#!/usr/bin/env perl

use Devel::Peek;

my $one         =            1        ;
my $num         =        0.001 * 1_000;

STDOUT->autoflush;
STDERR->autoflush;

for (['one', $one], ['num', $num]) {
    my $label = $_->[0];
    print "$label...\n";
    print "Before copying: original variable:\n";
    Devel::Peek::Dump($_->[1]);
    my $var = $_->[1];
    print "Copied:\n";
    Devel::Peek::Dump($var);
    printf("Integer value according to printf: %d\n", $var);
    print "After printf:\n";
    Devel::Peek::Dump($var);
    print "\n";
}

=for reference

use Data::Dumper;
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Sortkeys = 1;
local $Data::Dumper::Terse = 1;
use Config;
print Dumper(\%Config);

=cut

# Perls installed yesterday evening with
# perlbrew install-multiple --both ld -j 4 5.30.1
# and a bunch of CPAN stuff - Dist::Zilla and Test2 mostly - added earlier this morning
sam@chimera:timer-milestones$ perlbrew switch perl-5.30.1
sam@chimera:timer-milestones$ perl precision-weirdness.pl 2>&1 | tee brief-output
one...
Before copying: original variable:
SV = IV(0x15f58c8) at 0x15f58d8
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1
Copied:
SV = IV(0x1637138) at 0x1637148
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1
Integer value according to printf: 1
After printf:
SV = IV(0x1637138) at 0x1637148
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1

num...
Before copying: original variable:
SV = NV(0x15f5a10) at 0x15f5a28
  REFCNT = 1
  FLAGS = (NOK,pNOK)
  NV = 1
Copied:
SV = PVNV(0x15dc110) at 0x1637148
  REFCNT = 1
  FLAGS = (NOK,pNOK)
  IV = 1
  NV = 1
  PV = 0
Integer value according to printf: 1
After printf:
SV = PVNV(0x15dc110) at 0x1637148
  REFCNT = 1
  FLAGS = (IOK,NOK,pIOK,pNOK)
  IV = 1
  NV = 1
  PV = 0

sam@chimera:timer-milestones$ perlbrew switch perl-5.30.1-ld
sam@chimera:timer-milestones$ perl precision-weirdness.pl 2>&1 | tee brief-output-ld
one...
Before copying: original variable:
SV = IV(0x16cc778) at 0x16cc788
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1
Copied:
SV = IV(0x16df088) at 0x16df098
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1
Integer value according to printf: 1
After printf:
SV = IV(0x16df088) at 0x16df098
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1

num...
Before copying: original variable:
SV = NV(0x16df280) at 0x16cc8d8
  REFCNT = 1
  FLAGS = (NOK,pNOK)
  NV = 1
Copied:
SV = PVNV(0x16b3190) at 0x16df098
  REFCNT = 1
  FLAGS = (NOK,pNOK)
  IV = 1
  NV = 1
  PV = 0
Integer value according to printf: 0
After printf:
SV = PVNV(0x16b3190) at 0x16df098
  REFCNT = 1
  FLAGS = (NOK,pIOK,pNOK)
  IV = 0
  NV = 1
  PV = 0

sam@chimera:timer-milestones$ diff -uw brief-output brief-output-ld 
--- brief-output	2020-03-03 12:52:12.602120055 +0000
+++ brief-output-ld	2020-03-03 12:52:24.738169281 +0000
@@ -1,40 +1,40 @@
 one...
 Before copying: original variable:
-SV = IV(0x15f58c8) at 0x15f58d8
+SV = IV(0x16cc778) at 0x16cc788
   REFCNT = 1
   FLAGS = (IOK,pIOK)
   IV = 1
 Copied:
-SV = IV(0x1637138) at 0x1637148
+SV = IV(0x16df088) at 0x16df098
   REFCNT = 1
   FLAGS = (IOK,pIOK)
   IV = 1
 Integer value according to printf: 1
 After printf:
-SV = IV(0x1637138) at 0x1637148
+SV = IV(0x16df088) at 0x16df098
   REFCNT = 1
   FLAGS = (IOK,pIOK)
   IV = 1
 
 num...
 Before copying: original variable:
-SV = NV(0x15f5a10) at 0x15f5a28
+SV = NV(0x16df280) at 0x16cc8d8
   REFCNT = 1
   FLAGS = (NOK,pNOK)
   NV = 1
 Copied:
-SV = PVNV(0x15dc110) at 0x1637148
+SV = PVNV(0x16b3190) at 0x16df098
   REFCNT = 1
   FLAGS = (NOK,pNOK)
   IV = 1
   NV = 1
   PV = 0
-Integer value according to printf: 1
+Integer value according to printf: 0
 After printf:
-SV = PVNV(0x15dc110) at 0x1637148
+SV = PVNV(0x16b3190) at 0x16df098
   REFCNT = 1
-  FLAGS = (IOK,NOK,pIOK,pNOK)
-  IV = 1
+  FLAGS = (NOK,pIOK,pNOK)
+  IV = 0
   NV = 1
   PV = 0
sam@chimera:timer-milestones$ perlbrew switch perl-5.30.1
sam@chimera:timer-milestones$ perl -V:config_args
config_args='-de -Dprefix=/opt/perlbrew/perls/perl-5.30.1 -Aeval:scriptdir=/opt/perlbrew/perls/perl-5.30.1/bin';
sam@chimera:timer-milestones$ perlbrew switch perl-5.30.1-ld
sam@chimera:timer-milestones$ perl -V:config_args
config_args='-de -Dprefix=/opt/perlbrew/perls/perl-5.30.1-ld -Duselongdouble -Aeval:scriptdir=/opt/perlbrew/perls/perl-5.30.1-ld/bin';

Sam
-- 
Website: http://www.illuminated.co.uk 


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About