
Boost Users : 
Subject: Re: [Boostusers] problems with C++ integer types
From: Robert Ramey (ramey_at_[hidden])
Date: 20120131 12:45:56
Daryle Walker wrote:
> I haven't yet read the Usenet article you mentioned in your reply
> because I want to get out my initial response without influence.
> [I read it after writing the following. I think my post here is more
> useful.]
>
> 
>> From: Robert Ramey
>> Date: Sun, 29 Jan 2012 15:01:10 0800
>>
>> I'm very confused about a number of things related to C++ standard
>> and boost libraries
>> dealing with numeric types. Here are a few things that I'm not
>> getting.
>>
>> a) The standard says in section 18.3.2.1
>>
>> "Specializations shall be provided for each arithmetic type, both
>> floating point and integer, including bool.
>> The member is_specialized shall be true for all such specializations
>> of numeric_limits."
>> ...
>> "Nonarithmetic standard types, such as complex<T> (26.4.2), shall
>> not have specializations."
>>
>> and it section 18.3.2.4 numeric_limits members
>>
>> static constexpr bool is_bounded;
>>
>> "True if the set of values representable by the type is finite. [
>> Note: All builtin types are bounded.
>> This member would be false for arbitrary precision types.end note ]"
>>
>> So the question is: if one makes a "numeric type" like std::complex
>> (or safe integer
>> which I'm interested in right now). Should one define a
>> specialization for this new type?
>
> In my opinion, the qualifier is if the numeric concept is a (sub)set
> of the real numbers. If so, then they should have a
> std::numeric_limits specialization.
It seemed to me that any type which "acts like a number" should have
such a specialization. I had interpreted the quote from the standard
as an admonition that one should not specialize std::numeric_limits
for one's own types. I had overlooked the phrase "nonarithimetic
standard types". In my case my types IS arithmetic and it's NOT
standard so the above wouldn't apply. So I concluded that my
concerns were a false alarm. So, I've implemented
a specialization of std::numeric_limits for my special kind of
integer  which is OK by me. BUT, now I wonder about the idea
if placing my own code into the std namespace which I would
guess might raise other issues.
> Builtin floatingpoint: YES
> Builtin integers (signed or unsigned): YES
> Builtin characters or Boolean: Logically, NO. Actuality, YES, due to
> the C++ language defining them as integer types. (And they're usable
> as such.)
> UDT arbitrary integer: YES
> UDT arbitrary floating/real: YES
> UDT rational: YES
> UDT arbitrary continuedfraction rational/real: YES
>
> Complex: NO
> Modulo: NO
> Polynominals: NO
> (Math) Vectors: NO
> Matrices: NO
> Geometry: NO
I would say
modular integer or float: definitely yes.
decimal floats: definitely yes.
polynomials: maybe if the are used to render numbers. Heck any radix based
numbers
numbers rendered as rational numbers: yes
big/unbounded integers: definitely yes
arbitray precision numbers: definitely yes.
geometry, matrices, vectors, etc.: not likely
e.g.rational numbers rendered as a quotient of two integers
bounded = true
e.g.rational numbers rendered as a quotient of two arbitray length integers
bounded = false
etc. ...
>> The working is pretty specific, but then I can't see why
>> "is_bounded" is in there since
>> all builtin arithmetic types are bounded. Oh I see this now:
>> Required by LIA1.
>
> Isbounded wouldn't apply to arbitrary length/precision types.
I would say it applies and that it's value should be false.
>> b) boost/type_traits/is_integral.hpp
> numeric_limits is for the type's math properties.
Actually, it's not at all clear to me what the intended purpose is.
> is_integral is for the type's properties with respect to the C++ type
> system. It can be used for template metaprogramming.
I was surprised to find that is_integral, is is_signed, etc are not
implemented in terms of numeric_limits but rather are implemented
for just the built in types. This leads to the current situation:
I create a new type of integer:safe_integer, modular_integer or ....
which is intended to be used anyware an int or unsigned int can
be used. This intention is frustrated when I use
is_signed< modular_integer > ... /compile error
but
is_isigned<int> is OK
The current situation is "don't do that"  OK  but it means that I can't
implement anything that "works like an int" except for int itself. This
seems to be to violate what I would have expected the intention
of numeric_limits to be. If it can't do this  what was it intended
to be used for? if type_traits for built in types don't use it  then
why create it in the first place.
I'm not advocating for changing anything. I'm just trying to figure
out what this thing is good for.
> The "modular integer<modulus>" is the only one of these that should
> NOT get a specialization for numeric_limits.
100 % disagree with this. It seems to me that this is the
ideal use case for numeric_limits.
Note that there a number of small but annoying ambiguities here.
e.g. unsigned int acts like a modular integer  it rolls over without
problem. But compilers may emit warnings when overflow might
occur. I haven't looked at the is_modulo value for unsigned int.
I'm guessing that numeric_limits isn't used to the extent that it
was originally intended.
>All of the others
> conceptually represent realnumber values, and therefore should. None
> of these types are builtins, and therefore NEVER should get a
> is_integral specialization.
This distinction between builtins addins is the source of my
consternation. In principle, I would like to replace/extend any builtin
type with my own special variant. Which I can do. What's not
clear is what should be done with regards to numeric_limits for this
new type. Ideally, by specializing numeric_limits for my new type
I should be able to get "free" benefits from programs which use
numeric_limits to affect their behavior.
Robert Ramey
Boostusers list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net