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 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
> cpp_dec_float would be to have no guard digits at all, and round after each operation to exactly
> 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.

> So.... the situation we have now seems to be path of least resistance. It's somewhat inelegant
> 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 A. Bristow,
Prizet Farmhouse, Kendal LA8 8AB  UK
+44 1539 561830  07714330204

Boost list run by bdawes at, gregod at, cpdaniel at, john at