[Numeric Conversion] Documentation Notes/Questions

* 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. * 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. * 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? * How do size, width, and density relate to unlimited precision rationals? I imagine: size = infinity width = infinity density = ? * 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? * 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 * 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. 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. * 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. * 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; it would imply most double=>float conversions have undefined behavior. What does this mean, anyway? 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. 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. ?? -- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost

Dave Abrahams wrote: ... A good critique. I had much interest in using this library for a specific situation I had but I really couldn't figure out how to use it. I guess I ended up rolling my own. http://rrsd.com/blincubator.com/bi_library/safe-numerics/ Robert Ramey

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 away)
* 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.
OK. I will split the docs in a "quick users guide" and a separate "advanced" section.
* 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.
OK
* 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) ] defines. Doesn't it? V is the abstract value to represent and abt(h) is the abstract value of the highest number, what you called "whatever-the-max"
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.
Right
* 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."
Indeed.
* 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
OK
* 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 ;) Best -- Fernando Cacciola SciSoft Consulting, Founder http://www.scisoft-consulting.com

-----Original Message-----
From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Fernando Cacciola Sent: Thursday, November 01, 2012 6:34 PM To: boost@lists.boost.org Subject: Re: [boost] [Numeric Conversion] Documentation Notes/Questions
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.
I'm not clear why you have chosen to call this an 'abstract value'. 'decimal digit string' seems more explicit -though I can see that it might also be a hex of oct (or even bin) string. So would 'digit string value' be more immediately obvious? (It could be qualified as 'integer digit string'(99), 'decimal digit string' (1.2), 'fraction digit string' (.1234), 'hex integer digit string (FF), ...) But perhaps I'm missing something?
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.
Definitely! This is confusing stuff. Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com

Hi Fernando, Thanks for your very complete answers. I'm very much looking forward to the updated docs! on Thu Nov 01 2012, Fernando Cacciola <fernando.cacciola-AT-gmail.com> wrote:
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 away)
<snip>
Oh.. again I need to read the doc and get back. I've no idea what I meant ;)
Best
-- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost
participants (4)
-
Dave Abrahams
-
Fernando Cacciola
-
Paul A. Bristow
-
Robert Ramey