develooper Front page | perl.perl6.users | Postings from April 2021

Re: Comparing Int and Num

Thread Previous | Thread Next
From:
sisyphus
Date:
April 26, 2021 14:23
Subject:
Re: Comparing Int and Num
Message ID:
CADZSBj0qhPBdRs=xNPcoBk8mge5BjGpDpUN27KOPYwBFPQukXw@mail.gmail.com
On Sun, Apr 25, 2021 at 3:57 AM Ralph Mellor <ralphdjmellor@gmail.com>
wrote:

> On Fri, Apr 16, 2021 at 7:22 AM sisyphus <sisyphus359@gmail.com> wrote:
> >>
> > The conversion from int to num looks sane.
>
> Sounds good. :)
>
> So presumably our early tentative conclusion of what we hope
> will pan out is that if one wants precise IEEE float behaviour,
> one uses `num` instead of `Num`. Right?
>
>
Yes.


>
> > However, the second of those integers should assign to the double
> > 9.223372036854775e+18  (0x1.fffffffffffffp+62) - yet this happens only
> > for the 'num' case
>
> So that's happening in the `Num` type's storage, not its stringification,
> right?
>
>
Yes.


>
> > I don't think it's a big deal if that is deemed to be NOT buggy.
>
> OK.
>
> `Num` is considered an approximate float, `num` the exact one.
>
>
> > We would just have to be mindful of avoiding Nums when we're
> > not prepared to accept that the usual "round to nearest, ties to
> > even" rule might not be enforced.
>
> Is that about storage or stringification?
>
>
It's about storage.
Stringification, as presented by say(), reliably presents us with a value
that will assign to exactly the same value as was stored in the variable
that was passed to say().
Raku seems reliable in this .... perl is not.

Raku's stringification of nums via sprintf() is not so good because it
won't output more than 17 significant decimal digits (as mentioned
previously).
This is not an issue in terms of the "round-trip" consideration outlined in
the previous paragraph, but it can be an issue if you're wanting to get an
exact rational representation of the value held by the num/Num.

I'm still puzzled about raku's capability to represent the exact value
contained in a num as a rational - either in the form nu/de or as a decimal
floating point value.
In python3, both forms are available:
  $ python3 -c 'from fractions import
Fraction;print(Fraction.from_float(0.1));'
3602879701896397/36028797018963968

$ python3 -c 'print("%.55g" % (0.1))'
0.1000000000000000055511151231257827021181583404541015625

In perl, both forms are available:
C:\>perl -MMath::GMPq -le "print Math::GMPq->new(0.1)"
3602879701896397/36028797018963968

C:\>perl -e "printf '%.55g', 0.1;"
0.1000000000000000055511151231257827021181583404541015625

But in raku, I haven't yet found out how to do either.
I suspect that it's possible to achieve at least one of those two outputs
in raku, but I still don't know.
(I guess I could just use Inline::Perl5 ... not exactly my preferred option
... but a viable alternative, I would think.)


> Have you seen this active PR by Nicholas Clark?:
>
> https://github.com/MoarVM/MoarVM/pull/1472
>
>
I have now ;-)
I'll try to keep an eye on it as I'm interested to see what develops from
it.


> Do you understand it?
>
>
I definitely understand the considerations.
Somewhere (perhaps in this thread), I've recently mentioned that I've
implemented grisu3  in my perl5 module Math::MPFR.
I called it doubletoa() and it plagiarises code found at
http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf.
In fact, it's little other than a copy'n'paste of that code:

https://metacpan.org/source/SISYPHUS/Math-MPFR-4.16/grisu3.h
https://metacpan.org/source/SISYPHUS/Math-MPFR-4.16/grisu3.c

(I think I've duly accredited it, and I hope it's all legal .... someone
might like to let me know if it's not.)

I've compared it with what raku presents, and so far I've found complete
agreement when I have doubletoa() fall back to sprintf("%.17g"...) for the
~0.5% of values that it can't stringify..
By default, however, doubletoa() falls back to my "dragon4" implementation
- which is an option that Nicholas and Zoffix have both considered wrt raku.
For that default behaviour, I just compare with python3, But it's also
handy to have raku to check against for the sprintf fallback.

There was a grisu3 implementation that I came upon somewhere where they
enabled integer arithmetic for values requiring more than 64 bits.
I wondered whether they were implementing that as a means to reducing the
failure rate from ~0.5% to 0. (If so, I wonder whether raku should take
that approach.)
I also wonder about grisu3's capability to deal with larger precision (and
larger exponent) floating point types like long double and __float128. For
as long as raku doesn't accommodate these floating point types, then
there's no need to consider this - but for me, it is a consideration.
I sense that ryu might scale even worse than grisu3 - but I'm not really
qualified to be making such guesses.
I haven't looked into it - mainly because I'm happy enough with my own
"dragon4" implementation, named nvtoa(), again in my Math::MPFR module.
My main motivation for coming up with a grisu3 implementation was simply
that it would provide yet another check on the accuracy of my nvtoa()
implementation albeit wrt doubles only.

I should point out that my nvtoa() implementation of "dragon4" is not
really dragon4 - it's just a precursor to dragon4 (presented as tables 3
and 4) in the same paper by Steele and White in which they presented
dragon4 (in tables 5 to 13).
My implementation of that algorithm uses the GMP library for the big
integer arithmetic.
It does the same job as the authentic dragon4 (albeit less optimally, I
would think), and I'm happy enough with the way it scales for long double
and __float128 types - so I'll just stick with it for now.
I'd like to think that, one day, I'll go the extra yards and implement
dragon4 ... but don't hold your breath ;-)

As regards "Dragonbox" which Nicholas mentioned, all I could find was a
company selling math apps for kids .... so I'm not sure what that's about.


> One important thing is that Rakudo is quite unlike the `perl`
> approach as an implementation in the sense that:
>
> * Most of the code is Raku, so very high level, and relatively
>   understandable if one knows any of the language.
>
> * Another big chunk is nqp, which is essentially just a subset of
>   Raku. So that's approachable too.
>
> * The main VM to focus on is MoarVM. An outsider reviewer
>   wrote in 2017 that it they considered it clean code that is well
>   organized, written, documented, and tested.
>
> So, I don't know C, and I don't consider NQP especially easy to
> get into, so it's all a bit intimidating, but I have dipped into the
> various parts of the compiler, and have never felt "I have zero
> chance of ever understanding this even if I put in significant effort".
>
> So at some point, perhaps during our exchange here, I think
> it makes sense for me to anticipate me and/or you digging into
> the compiler's source code, whether it's Raku, nqp, or C
> (MoarVM is C89), and perhaps you'll find you will understand
> whatever code I find, or even dig in yourself.
>
>
> > Mind you, it's hard to work out just what rounding rule *is* being
> > enforced - it's definitely not one that I've ever encountered before.
>
> I think a useful objective, to be reached before filing a new issue,
> is to find out what intent is embodied in the relevant code. It may
> be that it's appropriate to verify that the intent has been achieved,
> or there are bugs relative to it, or that the intent needs to change.
>
> But it would be appropriate to know that before filing an issue. It
> might be that what's needed is a *doc* issue, or it might be that it's
> a MoarVM, or nqp, or Raku, or Rakudo issue.
>
>
> > Though there seems to be a pattern emerging:
> >  9223372036854775295 -  9223372036854775231 == 64
> > and from my initial post in this thread:
> > (18446744073709551615 - 1024) - (18446744073709551615 - 1088) == 64.
> >
> > I suspect some little optimization trick might be doing something
> unexpected.
>
> Perhaps. Hopefully we agree it would be good to know what's going on.
>
> And if it can be stated more usefully than "hey, it's approximate, deal",
> it would be great to distill a pithy explanation and add it to the doc at
> the very least. Or if it's just a weak implementation, it would be good
> to at least file an appropriate issue.
>
> Maybe also agree to some tests that can be added to roast to ensure it
> doesn't get worse in the face of any future changes such as optimizations,
> if indeed that's what's going on.
>
>
I think that when Num gets rounded, it is currently rounded to a value that
is within one ULP of the exact value.
Maybe that is considered to be a good enough approximation, and there's
deemed no need to specify rounding rules at all ?
Seriously - on thinking about it some more, I would regard that as quite
acceptable for a numeric type that is documented to be only an
approximation. (It's a bit unorthodox but, AFAIK.)


> >> I hope to get time to respond to your earlier posts this weekend.
> >
> > No rush, and please, don't stress over any of this.
>
> Thus far our exchange has been delightful. No stress. :)
>
> I love the Perl community, and respect the perl implementation, and
> acknowledge that Raku and Rakudo aren't yet remotely in the same
> league with Perl maturity wise. And Raku is much more ambitious
> and has a much smaller community. (Double understatement!)
>
> But Larry long ago persuaded me that what he was trying to pull off
> could actually be pulled off, and was worth pulling off for the long
> term sake of the Perl community and/or devs that have a Perl like
> mindset, even if they won't realize that until it's *extremely* evident,
> which may not be the case until around the end of this decade.
>
> In the meantime, I folk who care about Perl also caring about Raku
> is a godsend, especially when they're as friendly as you. :)
>
>
Heh ... I probably haven't always been so friendly towards raku.
I was initially irritated by Larry's decision to take the "perl" name and
apply it to his new venture - but this has, of course, now been remedied,
and I've put it in the past (where it belongs !!).

I don't think I'm a typical perl user. I'm attracted to perl because of the
convenient access to C libraries (most notably gmp and mpfr) that it
provides via XS.
That's not a reason that many perl users would put forward, and some people
would claim that there are better ways to conveniently access C libraries
than via perl's XS.
Those people are quite possibly correct - but XS is the way with which I'm
most familiar, and it has served me well for the last 20 years or so.

Oh ... and I should add that I mess (and obsess) with the types of issues
we've been discussing here strictly as a hobby.

Have a good weekend!
>

Thank you.

I'm still not quite sure what to make of raku's math. Use of
dragon4/grisu3/ryu is a definite plus, as regards stringification.
I'll continue to keep an eye on raku with interest, though I'm quite sure
that perl will continue to be my main goto.

Cheers,
Rob

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