Skip Menu |

This queue is for tickets about the List-MoreUtils CPAN distribution.

Report information
The Basics
Id: 113117
Status: resolved
Priority: 0/
Queue: List-MoreUtils

People
Owner: Nobody in particular
Requestors: PERLANCAR [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.413
Fixed in: 0.414_001



Subject: XS's minmax() sometimes return undef (perl >= 5.20)
% perl -MList::MoreUtils=minmax -MData::Dump -e'for(1..20) { my ($min, $max) = minmax(sprintf("%.4g", rand)); dd ($min,$max) }' (0.1824, 0.1824) (0.9667, 0.9667) (0.9628, 0.9628) (0.493, undef) (0.08401, 0.08401) (0.4284, 0.4284) (0.01188, 0.01188) (0.469, undef) (0.2213, 0.2213) (0.9549, 0.9549) (0.3523, 0.3523) (0.5689, 0.5689) (0.285, undef) (0.7718, 0.7718) (0.2286, 0.2286) (0.3367, 0.3367) (0.7222, 0.7222) (0.476, undef) (0.1387, 0.1387) (0.2435, 0.2435) Happens more often when I use sprintf format "%.3g". Always happens when I use "%.2g" or fewer digits. Also happens when I use sprintf format "f". Tested with List::MoreUtils 0.413. Doesn't happen with PP backend. Tested with perl 5.22 and perl 5.20. Doesn't happen with perl 5.18 or earlier. Ref: http://perlmonks.org/?node_id=1157951
On 2016-03-17 05:07:21, PERLANCAR wrote: Show quoted text
> % perl -MList::MoreUtils=minmax -MData::Dump -e'for(1..20) { my ($min, > $max) = minmax(sprintf("%.4g", rand)); dd ($min,$max) }' > (0.1824, 0.1824) > (0.9667, 0.9667) > (0.9628, 0.9628) > (0.493, undef) > (0.08401, 0.08401) > (0.4284, 0.4284) > (0.01188, 0.01188) > (0.469, undef) > (0.2213, 0.2213) > (0.9549, 0.9549) > (0.3523, 0.3523) > (0.5689, 0.5689) > (0.285, undef) > (0.7718, 0.7718) > (0.2286, 0.2286) > (0.3367, 0.3367) > (0.7222, 0.7222) > (0.476, undef) > (0.1387, 0.1387) > (0.2435, 0.2435) > > Happens more often when I use sprintf format "%.3g". Always happens > when I use "%.2g" or fewer digits. Also happens when I use sprintf > format "f". > > Tested with List::MoreUtils 0.413. Doesn't happen with PP backend. > > Tested with perl 5.22 and perl 5.20. Doesn't happen with perl 5.18 or > earlier. > > Ref: http://perlmonks.org/?node_id=1157951
More observations: * happens only if the stringified form has fewer digits after the dot than the format specified (here: three digits after the dot) * probably has to do something with COW: if I add Devel::Peek::Dump calls then I see the following pattern: With COW flag result is correct: SV = PV(0x15d6d30) at 0x157ff20 REFCNT = 2 FLAGS = (POK,IsCOW,pPOK) PV = 0x1579e80 "0.2769"\0 CUR = 6 LEN = 10 COW_REFCNT = 1 (0.2769, 0.2769) Without COW flag the undef happens: SV = PV(0x156ded0) at 0x158aee8 REFCNT = 2 FLAGS = (POK,pPOK) PV = 0x1698c40 "0.122"\0 CUR = 5 LEN = 10 (0.122, undef) (One liner used here: perl5.20.3 -MDevel::Peek -MList::MoreUtils=minmax -MData::Dump -e'for(1..100) { my ($min, $max) = minmax(map { Dump $_; $_ } sprintf("%.4g", rand)); dd ($min,$max) }' )
On 2016-03-17 16:23:01, SREZIC wrote: Show quoted text
> On 2016-03-17 05:07:21, PERLANCAR wrote:
> > % perl -MList::MoreUtils=minmax -MData::Dump -e'for(1..20) { my > > ($min, > > $max) = minmax(sprintf("%.4g", rand)); dd ($min,$max) }' > > (0.1824, 0.1824) > > (0.9667, 0.9667) > > (0.9628, 0.9628) > > (0.493, undef) > > (0.08401, 0.08401) > > (0.4284, 0.4284) > > (0.01188, 0.01188) > > (0.469, undef) > > (0.2213, 0.2213) > > (0.9549, 0.9549) > > (0.3523, 0.3523) > > (0.5689, 0.5689) > > (0.285, undef) > > (0.7718, 0.7718) > > (0.2286, 0.2286) > > (0.3367, 0.3367) > > (0.7222, 0.7222) > > (0.476, undef) > > (0.1387, 0.1387) > > (0.2435, 0.2435) > > > > Happens more often when I use sprintf format "%.3g". Always happens > > when I use "%.2g" or fewer digits. Also happens when I use sprintf > > format "f". > > > > Tested with List::MoreUtils 0.413. Doesn't happen with PP backend. > > > > Tested with perl 5.22 and perl 5.20. Doesn't happen with perl 5.18 or > > earlier. > > > > Ref: http://perlmonks.org/?node_id=1157951
> > More observations: > > * happens only if the stringified form has fewer digits after the dot > than the format specified (here: three digits after the dot) > > * probably has to do something with COW: if I add Devel::Peek::Dump > calls then I see the following pattern: > > With COW flag result is correct: > SV = PV(0x15d6d30) at 0x157ff20 > REFCNT = 2 > FLAGS = (POK,IsCOW,pPOK) > PV = 0x1579e80 "0.2769"\0 > CUR = 6 > LEN = 10 > COW_REFCNT = 1 > (0.2769, 0.2769) > > Without COW flag the undef happens: > SV = PV(0x156ded0) at 0x158aee8 > REFCNT = 2 > FLAGS = (POK,pPOK) > PV = 0x1698c40 "0.122"\0 > CUR = 5 > LEN = 10 > (0.122, undef) > > (One liner used here: > > perl5.20.3 -MDevel::Peek -MList::MoreUtils=minmax -MData::Dump > -e'for(1..100) { my ($min, $max) = minmax(map { Dump $_; $_ } > sprintf("%.4g", rand)); dd ($min,$max) }' > > )
Happens also with bleadperl (5.23.8). And with this setup (using %.1g) it always fails, even with older perls (5.14.x and up): perl5.20.3 -MTest::More=no_plan -MDevel::Peek -MList::MoreUtils=minmax -E 'my($min,$max)=minmax(map { Dump $_; $_ } sprintf "%.1g",rand()); ok defined $max'
Patched in df13089