develooper Front page | perl.perl5.porters | Postings from September 2021

Re: Missing sv_numeq() function?

Thread Previous | Thread Next
From:
sisyphus
Date:
September 14, 2021 14:02
Subject:
Re: Missing sv_numeq() function?
Message ID:
CADZSBj17onN+7yaKJJ0_dogE=mOhJwjiFyh7eZKxVjyKfDC+Cw@mail.gmail.com
I've given it a run and it looks pretty good here.

I came across one interesting little anomaly:
############################
use strict;
use warnings;
use Math::BigRat;
use Test::More;

use Inline C => <<'EOC';

int is_eq(SV * n1, SV * n2) {
  if(sv_numeq(n1, n2)) return 1;
  return 0;
}

EOC

my $bigq1 = Math::BigRat->new(
            '3602879701896397/36028797018963968'
            );
my $bigq2 = Math::BigRat->new(
           '1/10'
            );

cmp_ok($bigq1, '!=', $bigq2, "Rationals are unequal");
cmp_ok(is_eq($bigq1, $bigq2), '!=', 1, "sv_numeq detects inequality");

done_testing
#############################

This outputs:

ok 1 - Rationals are unequal
not ok 2 - sv_numeq detects inequality
#   Failed test 'sv_numeq detects inequality'
#   at sv_numeq.pl line 23.
#          got: 1
#     expected: anything else

Both of those rationals equate to the double 0.1. (The first is an exact
rational representation of the value contained in that double; the second
rational rounds to that same double.)
I don't know if anything could be done about that.
On investigation, it seems that sv_numeq() is performing the division
that's implicit in the rationals, resulting in 2 doubles that contain the
same value (0.1). Unsurprisingly it therefore returns true.

2 additional tests (based on my initial, somewhat hopeful, expectations)
that I ran were:

cmp_ok(is_eq(0.1, $bigq1), '==', 1, "sv_numeq agrees that 0.1 == \$bigq1");
cmp_ok(is_eq(0.1, $bigq2), '!=', 1, "sv_numeq agrees that 0.1 != \$bigq2");

which resulted in:

ok 3 - sv_numeq agrees that 0.1 == $bigq1
not ok 4 - sv_numeq agrees that 0.1 != $bigq2
#   Failed test 'sv_numeq agrees that 0.1 != $bigq2'
#   at sv_numeq.pl line 25.
#          got: 1
#     expected: anything else

Oh ... and I think there's a simple typo in the docs:
<quote>
    "sv_numeq"
        A convenient shortcut for calling "sv_numeq" with the "SV_GMAGIC"
        flag.
</quote>
I suspect the second occurrence of "sv_numeq" should be "sv_numeq_flags" ?

Cheers,
Rob


On Mon, Sep 13, 2021 at 1:59 AM Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
wrote:

> On Fri, 20 Aug 2021 11:55:00 +0100
> "Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:
>
> > I propose adding an API function
> >
> >    BOOL sv_numeq(SV *left, SV *right);
> >
> > to cover this.
> >
>
> Update: here's an initial attempt, including docs and XS::APItests:
>
>   https://github.com/leonerd/perl5/tree/sv_numeq
>
>
> Thinking further about this, I think I'd like to define a new SV_* flag
> to request that the function also perform operator overloading. This
> new sv_numeq() would recognise that flag, and I'd also add support to
> the existing sv_eq(). (Which, is stringy. In hindsight it should have
> been named sv_streq(), but too late now (unless we rename it maybe?))
>
>
> Perhaps it would be named something like `SV_TRYAMAGIC`. Or maybe the
> less cryptic `SV_OVERLOAD` (though we already have an unrelated flag,
> `SV_SKIP_OVERLOAD` which the various sv_2Xv_flags() functions all take).
>
> `SV_OVERLOAD` would be nice, except it's a bit messy having some
> _flags()-like functions that do overloading by default and have a flag
> to tell them not to, vs. other flagsy functions that don't but take a
> flag to tell them to.
>
>
> Unless.....
>
> Maybe I can solve all of these issues in one go, by making a new
> sv_streq_flags() which does overload by default, and put that behaviour
> in my new sv_numeq_flags() as well, then these functions can all respond
> to the same SV_SKIP_OVERLOAD flag in the same way. Then sv_eq() and
> sv_eq_flags() become wrappers of sv_streq_flags() which do pass the
> SV_SKIP_OVERLOAD flag. I think it would be nice to do overload by
> default as that's generally "the nice thing to do", and a flag to turn
> it off for specific circumstances.
>
>
> Thoughts?
>
> --
> Paul "LeoNerd" Evans
>
> leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
> http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
>

Thread Previous | 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