Boost logo

Boost :

Subject: Re: [boost] [Review Request] Multiprecision Arithmetic Library
From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2012-04-16 13:15:39


> -----Original Message-----
> From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]] On Behalf Of John
> Maddock
> Sent: Monday, April 16, 2012 11:38 AM
> To: boost_at_[hidden]
> Subject: Re: [boost] [Review Request] Multiprecision Arithmetic Library
>
> >> I'm not sure I follow you - what the std says is:
> >> static constexpr int digits10;
> >> 11 Number of base 10 digits that can be represented without change.
> >> 12 Meaningful for all specializations in which is_bounded != false.
> >
> > Could you please tell me where this is in ISO 14882:2011?
> > I can't find it.
>
> Section 18.3.2.4 para 13 (I'm looking at the final draft though so there may be detail changes to
the final
> std I guess).
>
> > <snip>
> >> Which I take as meaning that if you print at least max_digits10
> >> digits then you should always be able to get back to the same unique value.
> >
> > I agree.
> >
> > <snip>
> >
> >> Oh wait.... just looked at the code and I see the issue - you set
> >> max_digits10
> >> to digits10+1 which isn't enough, should be set to
> >> cpp_dec_float_total_digits10
> >> which is the largest number of digits possible in the number right?
> >> Making that change causes the test to pass, so committing, but please
> >> advise if that's upping max_digits10 too far ;-) Cheers, John.
> >
> > Wait John.
> >
> > It took me a long time to finally figure this out. And it gets back to
> > some of our original work with Paul Bristow. I believe that we
> > actually need to test for equality to within 1ULP, whereby the ULP in
> > this case is the least significant, potentially rounded and carried
> > base-10 "digit" in the limb containing the ULP of least precision in
> > cpp_dec_float.
> >
> > I need to actually add more intelligence to
> >
> > template <unsigned Digits10>
> > int cpp_dec_float<Digits10>::cmp_data(const array_type& vd) const.
> >
> > The current equality case includes *all* the guard limbs, even though
> > some are insignificant. I need to analyze the real number of identical
> > base-10 digits in LHS and RHS, take rounding into account and test for
> > equality not until the end of the limbs, but until one max_digits10,
> > potentially rounded and carried from (max_digits10 + 1).
> >
> > Can you follow me? Do you agree with this? It shouldn't be too
> > difficult to implement and I don't anticipate significant performance
> > loss due to analyzing two limbs in the array in base-10, possibly in
> > conjunction with lexical conversion.
> > And I would really like to give this a try.
> > With your permission, may I try this?
> > Am I on the right track?
>
> I don't know ;-)
>
> Here's what I think - firstly lets "Keep It Simple" - and if the digits are present in the
internal representation,
> then why *shouldn't* they be used for comparisons and printing out?
>
> Let me give you an example - if there are guard digits which aren't used for comparisons - could
you not
> get into a situation where two numbers which compare equal lead to different results after some
> sequence of arithmetic operations? IMO that would not be good, and at the very least could lead
to all
> kinds of confusions.

Like the many confusions caused by digits10 before max_digits10 was introduced.

Two numbers that could be distinguished displayed the same, which was very confusing, especially to
the majority whose grip on floating-point was less than secure ;-)

> Consider what GMP's mpf_t does - there are hidden guard digits that you don't see, which do take
part in
> comparisons and all arithmetic operations, on the other hand they don't provide a way to print
those out
> which makes round tripping impossible - which IMO is very annoying.
>
> On the other hand, MPFR takes a much less loose approach, and rounds everything to *exactly* the
> requested precision after each step, round tripping is also possible in this case. The equivalent
in
> cpp_dec_float would be to have no guard digits at all, and round after each operation to exactly
Digits10
> decimal places. While there may be use cases for that, I think we want to Keep It Simple for now
and not
> go down that road.

Agreed.
 
> So.... the situation we have now seems to be path of least resistance. It's somewhat inelegant
having
> max_digits10 so much larger than digits10, but it seems to me that nothing really bad can happen
here -
> just maybe that serialized numbers will occupy a touch more space on disk than expected?

And that any display using max_digits10 will look a bit odd, having so many potentially
insignificant digits.

I can't quite see why more than two or three guard digits should be needed? If we compare with the
built-in floating-point, then only two are needed from Kahan's formula even at 128-bit. So lots more
sort of feels untidy?

But John is right in saying that nothing too evil can happen from having too many.

Paul

---
Paul A. Bristow,
Prizet Farmhouse, Kendal LA8 8AB  UK
+44 1539 561830  07714330204
pbristow_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk