Boost logo

Boost :

Subject: Re: [boost] [Numeric Conversion] Documentation Notes/Questions
From: Fernando Cacciola (fernando.cacciola_at_[hidden])
Date: 2012-11-01 14:33:59

On 27-Oct-12 10:55 AM, Dave Abrahams wrote:

Hi Dave,

Interestingly, I thought a few days ago that I should force myself to
stop by the list in case there was something really important. I'm glad
I did!
I'm normally busy 24/7 but I'm starting to make room for all the
important things, not just the top most pressing (because they never go

> > * First thing to note: the documentation makes this library less
> approachable than it could be. In order to even begin, one has to
> bury onesself in terminology (the "Definitions" section). A
> super-quick "hello, world" example and a very short tutorial at the
> beginning would help a *lot*. numeric_cast is arguably the most
> generally-useful interface of the whole library and yet it's not even
> discussed until the end of the docs.
I will split the docs in a "quick users guide" and a separate "advanced"

> * It's not clear what the purpose of abt(x) is. In expressions, "x"
> usually means its value. When you introduce a mechanism like this, it
> would be a good idea to explain why it's needed. Most places, the use
> of "abstract" just seems to complicate things:
> "A ulp is a quantity whose abstract magnitude"
> what's wrong with
> "A ulp is a quantity whose magnitude"
> ??
> The end of the section on "Range and Precision" begins to explain why
> you want "abstract," but it takes the reader a long time to get to it.

That is needed to draw a distinction between the values that are
represented and the effective value of the representation.
I debated myself a lot whether such a concept was really needed, given
how odd it is, or if there was a better way, but couldn't find it.

The problem is that, when talking about the effects of a numeric
conversion, I need a thing that can be used to qualify and quantizie the
difference between the (effectively represented) values before and after
the conversion.
That is, in "(int)1.2" there are just two represented values, the
floating point that closely matches the decimal 1.2 and the integer 1,
yet I need to refer to the .2 in there that is getting lost and a useful
element to do that, IMO, is "the decimal number 1.2". I call that an
abstract value.

Without such a concept it is much more difficult to describe and bound
*in general terms* the sides effects of conversions, such as loose of
precision, overflow and underflow.

Having said that, you have a point and this needs to be explained and
justified right up front.

> * are next() and prev() always well-defined? Seems to me that an
> unlimited precision rational number type might not have them. Is that
> type not numeric?
Such a type is certainly numeric, but it represents a continuous field
as opposed to a discrete set.
In the current documentation, that all numeric types corresponds to
discrete sets is assumed (so we have next and prev, range, etc...)

In order to accommodate such a type, the documentation would have to be
overally revised and extended.

The fundamental difference is that range, hence overflow and underflow,
are not defined for such types. Similarly, precision is unbounded, so
this would have to be properly reflected in the docs.

> * How do size, width, and density relate to unlimited precision
> rationals? I imagine:
> size = infinity
> width = infinity
> density = ?
density could be said to be infinity as well, but I'd say is more
correct to consider it undefined.

Like I said, there needs to be a proper distinction between "discrete
and continuous" numeric types. Then use that to properly characterize
unlimited precision rationals (or plain integers for that matter)

> * This is slightly ambiguous:
> "This definition allows for a concise definition of subranged as
> given in the last section."
> "final section" would be clearer. A link would help too.

> * This is unclear:
> "Abstract intervals are easier to compare and overlap since
> only boundary values need to be considered."
> an example would help. How can one kind of thing be "easier to
> overlap" than another?
Oh.. I'm responding off the top of my head, and that is indeed unclear.
I'll read the doc to see if I figure out what did I mean.

> * Precision has a very non-generic description, being different for
> types with density 1 and other types. It's hard to see what use such
> a concept has, and as far as Google can tell it is not used anywhere
> outside the Definitions section
OK, I'll improve that.

In a way, a type with density 1, i.e. an integral number, simply has no
precision at all. But I wanted to be able to describe conversions
between types without branching out case by case, so I invented such
extended concept of precision.

> * Description of unsigned types, I think, is wrong:
> Notice that a numeric type, such as a C++ unsigned type, can define
> that any V does not overflow by always representing not V itself
> but the abstract value U = [ V % (abt(h)+1) ], which is always in
> range.
> Seems to me that the abstract values represented by an unsigned
> integer type are not the set of whole numbers, but the set of whole
> numbers modulo whatever-the-max+1-is.

And that is exactly what the expression

U = [ V % (abt(h)+1) ]


Doesn't it?

V is the abstract value to represent

and abt(h) is the abstract value of the highest number, what you called

> That's a well-defined
> mathematical abstraction, isn't it? Is there a problem with that,
> such as multiplication not working properly (I don't think so)?
> * There seems to be a contradiction here:
> If V >= abt(l) and V <= abt(h), V is representable (can be
> represented) in the type T
> ...
> Given an abstract value V represented in the type T as v, the
> roundoff error of the representation is the abstract difference: (
> abt(v)-V).
> If V is not representable in type T, can you write formulae using its
> representation in type T? Given what I read later, maybe you should
> have just said "exactly representable" in the first phrase.
You are right. It should he "exactly representable"

> * s/at most/less than/?:
> Because a correctly rounded representation is always one of adjacents
> of the abstract value being represented, the roundoff is guaranteed
> to be at most 1ulp.
Oh, you're right. It cannot be 1 ulp, has to be less.

> * s/cannot be represented/cannot be exactly represented/ ?:
> The integer number -1 can be exactly represented in Int, Real
> and Whole, but cannot be represented in Cardinal, yielding
> negative overflow.

> * Uh-oh:
> Floating to Floating conversions are defined only if N is
> representable; if it is not, the conversion has undefined behavior.
> in many places you've used "representable" to mean "exactly
> representable," but I can't believe you mean that here;

Right, and indeed I didn't here.

> it would imply
> most double=>float conversions have undefined behavior.
> What does this mean, anyway?

That's worded all wrong. What it should have said is "IFF N is within
range" (or something like that)

> If an abstract value can be "inexactly
> representable," aren't all abstract values representable if there's at
> least one abstract value that's exactly representable? Just convert
> to that and you're done.

Indeed. That meant to cover for overflow/underflow, not loose of precision.

> I think you need to give some serious
> thought to the definition of "representable."

> * s/then/so/:
> R(X) & R(Y) == R(X), then X->Y is not subranged. Thus, all
> values of type X are representable in the type Y.
> (b) Y->X:
> R(Y) & R(X) == R(Y), then Y->X is not subranged. Thus, all

> * What's the difference between a policy and a "parameter that defines
> the conversion" in
> It can optionally take some policies which can be used to customize
> its behavior. The Traits parameter is not a policy but the parameter
> that defines the conversion.
> ??
Oh.. again I need to read the doc and get back. I've no idea what I meant ;)


Fernando Cacciola
SciSoft Consulting, Founder

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