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
> 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 220.127.116.11 para 13 (I'm looking at the final draft though so there may be detail changes to
> 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
> 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
> 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
> 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
> comparisons and all arithmetic operations, on the other hand they don't provide a way to print
> 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
> 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
> 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
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 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