Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Q: numeric_limits<T> in Draft C++ Standard

0 views
Skip to first unread message

Brian Parker

unread,
Mar 12, 1997, 3:00:00 AM3/12/97
to

JYou...@vggas.com (James Youngman) wrote:
>...
>Reading the documentation for the numeric attributes template, I note that the
>characteristics of a type are determined by calling member functions of a
>template class numeric_limits<T>.

>I have recently been using a large C++ library that provides (excellent)
>support for arbitrary-precision math, called CLN. CLN is compatible with
>compilers tracking the standard but does not provide a template specialisation
>for numeric_limits<cl_F>. I bagan to think about providing this for cl_F.
>...

According to the Dec 96 draft you are explicitly disallowed from adding your
own type specialisations to numeric_limits; in fact you can check whether a
template parameter is a built-in type by testing
numeric_limits<T>::is_specialized.

>I would suggest (as an addition) something similar to
>
>template <class T> numeric_instance_limits {
>public:
> T min(const T&) throw();
> // ...
>};

That may be a useful user-supplied extension, though I don't think it should
necessarily be specified as part of the standard.

,Brian Parker (bpa...@gil.com.au)


[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]


David Vandevoorde

unread,
Mar 16, 1997, 3:00:00 AM3/16/97
to

Brian Parker wrote:
[...]

> in fact you can check whether a
> template parameter is a built-in type by testing
> numeric_limits<T>::is_specialized.

Nope, this won't work for array, pointer and reference types.
The method you describe only works for fundamental types.

Daveed

Nathan Myers

unread,
Mar 22, 1997, 3:00:00 AM3/22/97
to

David Vandevoorde <dav...@vandevoorde.com> writes:

>Brian Parker wrote:
>> in fact you can check whether a
>> template parameter is a built-in type by testing
>> numeric_limits<T>::is_specialized.

>Nope, this won't work for array, pointer and reference types.
>The method you describe only works for fundamental types.

Anyway, users are allowed (encouraged) to specialize numeric_limits<>
for their own numeric types. Hence, is_specialized only tells you
whether the other members are meaningful. If you really need to know
whether a parameter a built-in type, you must define your own is_builtin
traits template, and specialize it appropriately yourself -- not such a
big job. Here it is for the numeric types. With partial specialization
you can get the pointers as well.

template <class T> struct is_builtin { static const bool is = false; };
struct builtin_base { static const bool is = true; };

template<> struct is_builtin<char> : public builtin_base {};
template<> struct is_builtin<int> : public builtin_base {};
template<> struct is_builtin<short> : public builtin_base {};
template<> struct is_builtin<long> : public builtin_base {};
template<> struct is_builtin<unsigned char> : public builtin_base {};
template<> struct is_builtin<signed char> : public builtin_base {};
template<> struct is_builtin<unsigned int> : public builtin_base {};
template<> struct is_builtin<unsigned short> : public builtin_base {};
template<> struct is_builtin<unsigned long> : public builtin_base {};
template<> struct is_builtin<wchar_t> : public builtin_base {};
template<> struct is_builtin<double> : public builtin_base {};
template<> struct is_builtin<float> : public builtin_base {};
template<> struct is_builtin<long double> : public builtin_base {};


Nathan Myers
n...@cantrip.org

David Vandevoorde

unread,
Mar 24, 1997, 3:00:00 AM3/24/97
to

Nathan Myers wrote:
[...]

> Anyway, users are allowed (encouraged) to specialize numeric_limits<>
> for their own numeric types.

I'm not sure that CD2 supports you:

[lib.limits] 18.2.1/4:

Non-fundamental types, such as complex<T> (26.2.2),
shall not have specializations.

It is also implicit (sort of) in:

[lib.numeric.limits] 18.2.1.1/1

The member is_specialized makes it possible to
distinguish between fundamental types, which have
specializations, and non-scalar types, which do not.

Those two seem to disable the freedom to specialize in std::
offered in [lib.reserved.names] 17.3.3.1/1 for the case of
numeric_limits. (Or at least, it makes it unclear.)

Daveed

Ross Smith

unread,
Mar 24, 1997, 3:00:00 AM3/24/97
to

Nathan Myers wrote:
>
> Anyway, users are allowed (encouraged) to specialize numeric_limits<>
> for their own numeric types. Hence, is_specialized only tells you
> whether the other members are meaningful. If you really need to know
> whether a parameter a built-in type, you must define your own is_builtin
> traits template, and specialize it appropriately yourself -- not such a
> big job.

Not true. From the [lib.limits] section (18.2.1 in the Dec-96 draft):

Non-fundamental types, such as complex<T> (_lib.complex_), shall
not have specializations. ... The member is_specialized makes it


possible to distinguish between fundamental types, which have
specializations, and non-scalar types, which do not.

I think this makes it pretty clear that numeric_limits is strictly
confined to the primitive types -- library implementors are *not*
allowed to specialise it for their own types.

--
Ross Smith .................................... Wellington, New Zealand
Webmaster, EDS (New Zealand) Ltd ....... <mailto:ross....@nz.eds.com>
"I'm as interested as anybody else in all the things no decent
person would be interested in." -- Ashleigh Brilliant

Brian Parker

unread,
Mar 24, 1997, 3:00:00 AM3/24/97
to

n...@best.com (Nathan Myers) wrote:

>Anyway, users are allowed (encouraged) to specialize numeric_limits<>
>for their own numeric types.

> ...

>Nathan Myers
>n...@cantrip.org

It would seem to make sense to allow users to define their own
specialisations, however the Dec. 96 draft says "Non-fundamental types
such
as complex<T> shall not have specialisations." and "The member


is_specialized makes it possible to distinguish between fundamental
types,

which have specialisation, and non-scalar types, which do not."

Is this a bug in the draft, or have I missed something?

> ...


>If you really need to know
>whether a parameter a built-in type, you must define your own is_builtin

>traits template, and specialize it appropriately yourself.
> ..

Agreed, having a traits class to identify built-in types is very useful
for
optimised functions in generic programming; so useful in fact that it
would
have made a useful library addition, IMHO.

,Brian Parker (bpa...@gil.com.au)

Nathan Myers

unread,
Apr 6, 1997, 4:00:00 AM4/6/97
to

David Vandevoorde <dav...@vandevoorde.com> writes:

>Nathan Myers wrote:
>> Anyway, users are allowed (encouraged) to specialize numeric_limits<>
>> for their own numeric types.

>I'm not sure that CD2 supports you:


>
>[lib.limits] 18.2.1/4:
> Non-fundamental types, such as complex<T> (26.2.2),
> shall not have specializations.

This is meant to exclude non-scalars. The wording cited is an unfortunate
result of "too many cooks"; it used to say "do not have" and somebody
decided that was too descriptive and not *normative* enough.

>It is also implicit (sort of) in:
>[lib.numeric.limits] 18.2.1.1/1
>

> The member is_specialized makes it possible to
> distinguish between fundamental types, which have

> specializations, and non-scalar types, which do not.
>
>Those two seem to disable the freedom to specialize in std::
>offered in [lib.reserved.names] 17.3.3.1/1 for the case of
>numeric_limits. (Or at least, it makes it unclear.)

Here the distinction is clearer: "fundamental" is distinguished
from "non-scalar". It may be the only definition of "fundamental"
in the Draft.

For definitive judgments on the rationale for the numeric_limits<>
template, ask Todd Veldhuizen.

Nathan Myers
n...@cantrip.org

Nathan Myers

unread,
Apr 7, 1997, 3:00:00 AM4/7/97
to

Ross Smith <ross....@nz.eds.com> writes:
>Nathan Myers wrote:
>>
>> Anyway, users are allowed (encouraged) to specialize numeric_limits<>
>> for their own numeric types.

>Not true. From the [lib.limits] section (18.2.1 in the Dec-96 draft):


>
> Non-fundamental types, such as complex<T> (_lib.complex_), shall

> not have specializations. ... The member is_specialized makes it


> possible to distinguish between fundamental types, which have
> specializations, and non-scalar types, which do not.
>

>I think this makes it pretty clear that numeric_limits is strictly
>confined to the primitive types -- library implementors are *not*
>allowed to specialise it for their own types.

Sorry, the quoted text distinguishes scalars from non-scalars.

It was specifically intended that users would specialize
numeric_limits<> for their own numeric types. Any evidence you
find that suggests otherwise is spurious.

James Kanze

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

n...@best.com (Nathan Myers) writes:

|> Ross Smith <ross....@nz.eds.com> writes:
|> >Nathan Myers wrote:
|> >>
|> >> Anyway, users are allowed (encouraged) to specialize numeric_limits<>
|> >> for their own numeric types.
|>
|> >Not true. From the [lib.limits] section (18.2.1 in the Dec-96 draft):
|> >
|> > Non-fundamental types, such as complex<T> (_lib.complex_), shall
|> > not have specializations. ... The member is_specialized makes it
|> > possible to distinguish between fundamental types, which have
|> > specializations, and non-scalar types, which do not.
|> >
|> >I think this makes it pretty clear that numeric_limits is strictly
|> >confined to the primitive types -- library implementors are *not*
|> >allowed to specialise it for their own types.
|>
|> Sorry, the quoted text distinguishes scalars from non-scalars.
|>
|> It was specifically intended that users would specialize
|> numeric_limits<> for their own numeric types. Any evidence you
|> find that suggests otherwise is spurious.

Well, if the quoted text is accurate, and your description of the intent
is correct (and I've no reason to doubt either), then the text is very
misleading. Section 3.9.1 purportedly gives an exhaustive list of the
fundamental types, and user defined numeric types are NOT fundamental
types.

--
James Kanze home: ka...@gabi-soft.fr +33 (0)1 39 55 85 62
office: ka...@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --

Brian Parker

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

n...@best.com (Nathan Myers) wrote:
>...

>>[lib.limits] 18.2.1/4:
>> Non-fundamental types, such as complex<T> (26.2.2),
>> shall not have specializations.

>This is meant to exclude non-scalars. The wording cited is an unfortunate
>result of "too many cooks"; it used to say "do not have" and somebody
>decided that was too descriptive and not *normative* enough.

Which begs the question, if complex numbers are not scalars, then what
is the definition of "scalar" and "non-scalar" for user-defined types?
(so that one knows which of their user-defined types are allowed to
specialise numeric_limits<>).

BTW, has anyone submitted an official comment on this issue to ensure
that it gets fixed?

,Brian Parker (bpa...@gil.com.au)

Nathan Myers

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

James Kanze <james-alb...@vx.cit.alcatel.fr> writes:
>n...@best.com (Nathan Myers) writes:
>|> Ross Smith <ross....@nz.eds.com> writes:
>|> > [CD2 reads:]

>|> > Non-fundamental types, such as complex<T> (_lib.complex_), shall
>|> > not have specializations. ... The member is_specialized makes it
>|> > possible to distinguish between fundamental types, which have
>|> > specializations, and non-scalar types, which do not.
>|>
>|> It was specifically intended that users would specialize
>|> numeric_limits<> for their own numeric types. Any evidence you
>|> find that suggests otherwise is spurious.
>
>Well, if the quoted text is accurate, and your description of the intent
>is correct (and I've no reason to doubt either), then the text is very
>misleading. Section 3.9.1 purportedly gives an exhaustive list of the
>fundamental types, and user defined numeric types are NOT fundamental
>types.

I agree that it's confusing. Some of the people who edited the Draft
were convinced that its only purpose was to describe what components
must appear in an implementation. The idea was that the standard could
not dictate what users would or would not specialize anyway, so the
language above only talks about the standard components. However, there
is plenty of text elsewhere about what users are allowed to do.

I have entered an issue to recommend inserting the word "standard"
after "Non-fundamental", above. Those of you have written a
FixedPoint class are assured that you *can* specialize (e.g.)
std::numeric_limits<FixedPoint>.

Nathan Myers
n...@cantrip.org
http://www.cantrip.org/

Bradd W. Szonye

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Brian Parker <bpa...@gil.com.au> wrote in article
<5ifsau$1...@netlab.cs.rpi.edu>...

> n...@best.com (Nathan Myers) wrote:
> >...
> >>[lib.limits] 18.2.1/4:
> >> Non-fundamental types, such as complex<T> (26.2.2),
> >> shall not have specializations.
>
> >This is meant to exclude non-scalars. The wording cited is an
unfortunate
> >result of "too many cooks"; it used to say "do not have" and somebody
> >decided that was too descriptive and not *normative* enough.
>
> Which begs the question, if complex numbers are not scalars, then what
> is the definition of "scalar" and "non-scalar" for user-defined types?
> (so that one knows which of their user-defined types are allowed to
> specialise numeric_limits<>).

But complex numbers are *not* scalars. They are two-dimensional vectors.
--
Bradd W. Szonye
bra...@concentric.net

Brian Parker

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

"Bradd W. Szonye" <bra...@concentric.net> wrote:
> ...

>But complex numbers are *not* scalars. They are two-dimensional vectors.
>--
>Bradd W. Szonye
>bra...@concentric.net

Well, yes they can be viewed as an ordered pair, but in other contexts
such as a linear space they play the role of scalars. My point was
that the term non-scalar is not particularly well-defined, especially
when one considers arbitrary user-defined types. Therefore, the
paragraph in the draft "The member is_specialised makes it possible to
distinguish between fundamental types, which have specialisations, and
non-scalar types, which do not" is, I think, also not well-defined.

,Brian Parker (bpa...@gil.com.au)

Bradd W. Szonye

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

I wrote in article <5igedg$5...@netlab.cs.rpi.edu>...

> Brian Parker <bpa...@gil.com.au> wrote in article
> >

> > [If] complex numbers are not scalars, then what


> > is the definition of "scalar" and "non-scalar" for user-defined types?
>

> But complex numbers are *not* scalars. They are two-dimensional vectors.

Sorry to reply to my own post, but as David Vandevoorde made me realize in
email, my statement above is confusing to C++ programmers.

By "two-dimensional vectors" I don't mean a C++ vector<> of vector<>s, I
mean the linear algebra concept of a vector describing a position in a
plane.

I'd have to dig out my old linear algebra texts to give a mathematically
accurate definition of "scalar," but I think a good layman's definition
would be "a linear value which can be used to scale values, vectors, and
matrices." Since complex numbers are non-linear, they are not scalars. (I
truly hope that saying this doesn't get me lambasted again by the real
mathemeticians in the audience.)

Generally, there is a one-to-one mapping between a scalar type and either
real numbers or integers; there is no such mapping for complex numbers. I
imagine there are some applications in linear algebra and electrical
engineering where you might treat a complex number as a scaling factor, but
I don't think that's quite the same as treating one as a scalor. (Question
for mathemeticians: is complex multiplication a kind of cross-product? It's
been too long since I've used either extensively.)

>From a practical standpoint: the definition of numeric_limits<> isn't
well-suited to representing the traits of non-linear numbers. It's
concerned with minima, maxima, and granularity, which are all concepts that
do not translate well into two-dimensional numbers.


--
Bradd W. Szonye
bra...@concentric.net

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Oleg Zabluda

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Bradd W. Szonye <bra...@concentric.net> wrote:
: But complex numbers are *not* scalars. They are two-dimensional vectors.

They are two-dimentional vectors over R, infinite-dimentional vectors
over Q, and one-dimentional vectors over C. Since they also form a
field (can multiply and divide) they well qualify to be called scalars.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.

David A. Cuthbert

unread,
Apr 12, 1997, 3:00:00 AM4/12/97
to

Bradd W. Szonye <bra...@concentric.net> wrote:
>By "two-dimensional vectors" I don't mean a C++ vector<> of vector<>s, I
>mean the linear algebra concept of a vector describing a position in a
>plane.
>
>I'd have to dig out my old linear algebra texts to give a mathematically
>accurate definition of "scalar," but I think a good layman's definition
>would be "a linear value which can be used to scale values, vectors, and
>matrices." Since complex numbers are non-linear, they are not scalars. (I
>truly hope that saying this doesn't get me lambasted again by the real
>mathemeticians in the audience.)

Well, I'm not a real mathematician (I only play one, on occasion, in
grad school :-), but I take issue with your assertion that a complex
number is a non-linear entity. Note that the reals are a proper
subset of the complex numbers -- this would mean that the reals are
non-linear!

I had better hope that complex numbers are scalars. Otherwise, I (and
thousands of other engineers) have been doing integration improperly
since Riemann invented them way back when.

>Generally, there is a one-to-one mapping between a scalar type and either
>real numbers or integers; there is no such mapping for complex numbers.

Generally? No, this is a special case for reals and integers. :-)

>(Question
>for mathemeticians: is complex multiplication a kind of cross-product? It's
>been too long since I've used either extensively.)

No; the product of (a + jb) (c + jd), where j = Sqrt[-1], is what
you'd expect: ac + ajd + jbc + jjbd = (ac - bd) +j(ad + bc).

The cross product is only defined for 3-tuples and is a 3-tuple:
a b c
{ a, b, c } x { d, e, f } == Det[ d e f ] == { ce - bf, af - cd, bd - ae }
i j k
The dot product (i.e., typical inner product) of 2 2-tuples is
{ a, b } . { c, d } == ac + bd (a scalar). Neither of these represent
products of complex numbers.

I think you're confusing the representation of points in 2-space. I
can represent a point P as the 2-tuple { x, y } or as the complex
number x + jy. This does not mean that complex numbers are 2-tuples.

>From a practical standpoint: the definition of numeric_limits<> isn't
>well-suited to representing the traits of non-linear numbers. It's
>concerned with minima, maxima, and granularity, which are all concepts that
>do not translate well into two-dimensional numbers.

It has nothing to do with non-linearity; the reals as represented in
IEEE format are non-linear (but they approximate the linear quality
fairly well; they are linear up to their granularity limit).

Complex numbers, however, do not have order. <, <=, >, and >= are not
well-defined operators on them; hence, the normal notions of maxima
and minima make no sense. Granularity makes no sense without a
specified representation.

*However*, I think a class designer would be doing users a disservice
by leaving these quantities undefined. Perhaps this doesn't fit into
numeric_limits, but the class should specify the max, min, and
granularity for a and b (and/or r and theta) for one or both of the
representations: a + jb; r ( Cos[theta] + j Sin[theta] ).
--
David A. Cuthbert (henry.ece.cmu.edu!dacut)
Graduate Student, Electrical and Computer Engineering
Data Storage Systems Center, Carnegie Mellon University

Bradd W. Szonye

unread,
Apr 12, 1997, 3:00:00 AM4/12/97
to

I must apologize for my unfounded assertion that complex numbers are not
scalars. Folks with more experience than I have set me straight on this
subject. Reals and complex numbers are in fact scalars; integers are not
(since they do not satisfy the requirements for a scalar field, in
particular the property that a * x = b has a solution).

Now, I still don't think that complex<> fits the model of
numeric_limits<>
very well; it is hard to find a sensible definition for several of the
members of numeric_limits< complex<> >. However, the problem isn't with
the
two templates; it's the use of the term "scalar" in the definition of
numeric_limits<>. Perhaps a better requirement is:

"The template numeric_limits<> shall have specializations only for the
basic (integral and floating-point) types. Users of the template may
specialize it for user-defined types where there is a mapping to
integers
or real numbers, or where the members of numeric_limits<> are otherwise
meaningful for the type. [Note: None of the standard library types have
meaningful definitions for the members of numeric_limits<>. In
particular,
there is no specialization for complex<>. Also note that, since users
may
specialize numeric_limits<>, the template is not useful for
distinguishing
basic types from library types.]"

The verbiage isn't that great, but I think it expresses the intent of
the
committee better than the current version.


--
Bradd W. Szonye
bra...@concentric.net

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

James Kanze

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

n...@best.com (Nathan Myers) writes:

|> James Kanze <james-alb...@vx.cit.alcatel.fr> writes:
|> >n...@best.com (Nathan Myers) writes:
|> >|> Ross Smith <ross....@nz.eds.com> writes:
|> >|> > [CD2 reads:]
|> >|> > Non-fundamental types, such as complex<T> (_lib.complex_), shall

|> >|> > not have specializations. ... The member is_specialized makes it


|> >|> > possible to distinguish between fundamental types, which have

|> >|> > specializations, and non-scalar types, which do not.
|> >|>
|> >|> It was specifically intended that users would specialize
|> >|> numeric_limits<> for their own numeric types. Any evidence you
|> >|> find that suggests otherwise is spurious.
|> >
|> >Well, if the quoted text is accurate, and your description of the intent
|> >is correct (and I've no reason to doubt either), then the text is very
|> >misleading. Section 3.9.1 purportedly gives an exhaustive list of the
|> >fundamental types, and user defined numeric types are NOT fundamental
|> >types.
|>
|> I agree that it's confusing. Some of the people who edited the Draft
|> were convinced that its only purpose was to describe what components
|> must appear in an implementation. The idea was that the standard could
|> not dictate what users would or would not specialize anyway, so the
|> language above only talks about the standard components. However, there
|> is plenty of text elsewhere about what users are allowed to do.

But the real confusion is the use of the word "fundamental". In other
contexts in the standard (e.g.: section 3.9.1), and I think in the C
standard as well (although I don't have my copy here to check), it is
used to refer to a finite list of types defined by the language itself.
In C++: char, signed char, unsigned char, short, unsigned short, int,
unsigned int, long, unsigned long, float, double and long double. My
interpretation of fundamental is that this list is exhaustive. There
are NO other fundamental types, and a user cannot define a fundamental
type (since a class is never a fundamental type).

Using this interpretation, of course, the phrase "to distinguish between
fundamental types [...] and non-scalar types" makes no sense, since
there are types which are neither fundamental nor non-scalar (a user
defined BigInt, for example).

Wouldn't it be better to word the entire section uniquely in terms of
scalar vs. non-scalar, with perhaps an added phrase to the effect that
the only scalar types defined in the standard are the fundamental
arithmetic types? Or, if we adopt the point of view of those who
changed the original wording: drop all references to scalar
vs. non-scalar, and simply state that the implementation will provide
specializations for all fundamental arithmetic types, and no others.
(If this is done, I would like to see at least a non-normative note that
the intent is that users will provide specializations for user defined
scalar types, and not for other types.)

--
James Kanze home: ka...@gabi-soft.fr +33 (0)1 39 55 85 62
office: ka...@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Brian Parker

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

"Bradd W. Szonye" <bra...@concentric.net> wrote:
>...

>I'd have to dig out my old linear algebra texts to give a mathematically
>accurate definition of "scalar," but I think a good layman's definition
>would be "a linear value which can be used to scale values, vectors, and
>matrices." Since complex numbers are non-linear, they are not scalars. (I
>truly hope that saying this doesn't get me lambasted again by the real
>mathemeticians in the audience.)

I don't think that being "linear" or ordered is a requirement for
scalars. In linear algebra, scalars are things used as scalars (or is
that too tautological :-) ) i.e. numbers that are used in that role in
a linear space.

>Generally, there is a one-to-one mapping between a scalar type and either

>real numbers or integers; there is no such mapping for complex numbers. I

I don't think this is accurate, for example a finite field could be
used as a scalar but it is certainly not one-one with R or Z (in fact,
Z is not a field and so couldn't be used as a scalar)

(real mathematicians in the audience also feel free to lambast me on
any of the preceeding points).

>>From a practical standpoint: the definition of numeric_limits<> isn't
>well-suited to representing the traits of non-linear numbers. It's
>concerned with minima, maxima, and granularity, which are all concepts that
>do not translate well into two-dimensional numbers.

I think this is the crux of the matter, numeric_limits is only useful
for ordered sets and complex is not ordered; whether the type can be
used as a scalar is irrelevant.

In summary, I think that the line in the draft-
"The member is_specialised makes it possible to
distinguish between fundamental types, which have specialisations, and
non-scalar types, which do not" should be changed to
"The member is_specialised makes it possible to distinguish between
fundamental types, which have specialisations, and types where it
makes no sense to specialise, which do not" i.e. it is self-fulfilling
and hence redundant and should be removed.

.Brian parker (bpa...@gil.com.au)

Brian Parker

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

James Kanze <james-alb...@vx.cit.alcatel.fr> wrote:
> ...

>Wouldn't it be better to word the entire section uniquely in terms of
>scalar vs. non-scalar, with perhaps an added phrase to the effect that
>the only scalar types defined in the standard are the fundamental
>arithmetic types? Or, if we adopt the point of view of those who
>changed the original wording: drop all references to scalar
>vs. non-scalar, and simply state that the implementation will provide
>specializations for all fundamental arithmetic types, and no others.
>(If this is done, I would like to see at least a non-normative note that
>the intent is that users will provide specializations for user defined
>scalar types, and not for other types.)

Yes, IMHO the simplest fix would be to simply remove the phrases
"Non-fundamental types such as complex<T> shall have no
specialisations" and "The member is_specialised makes it possible to


distinguish between fundamental types, which have specialisations, and

non-scalar types, which do not."

[lib.limits] paragraph 2 specifies that the fundamental types shall
have specialisations, and I don't see any advantage in restricting
which other types are specialised- after all, no one is going to
provide an additional specialisation unless it is appropriate and
useful to do so, and, anyway, I don't think there is a simple
criterion the standard could give to indicate which other types are
appropriate for numeric_limits<> specialisation.

,Brian Parker (bpa...@gil.com.au)

Oleg Zabluda

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

Brian Parker <bpa...@gil.com.au> wrote:
: I don't think this is accurate, for example a finite field could be

: used as a scalar but it is certainly not one-one with R or Z (in fact,
: Z is not a field and so couldn't be used as a scalar)

: (real mathematicians in the audience also feel free to lambast me on
: any of the preceeding points).

I am a real mathematician, and you are right. In mathematics a
"scalar" is always used in conjunction with a "vector". Vectors
are elements of a vector space. Vector space is a module over
a field (any field). A is a module over B means that one must be
able to multiply elements of A by elements of B. Being a field
means that one must be able to add, subtract, multiply and divide
it's elements.

And, of course, mathematical scalars have nothing to do with
C++ scalars, as well as corresponding vectors:

Arithmetic types (_basic.fundamental_), enumeration types,
pointer types, and pointer to member types (_basic.compound_),
and cv-qualified versions of these types (_basic.type.qualifier_)
are collectively called scalar types.

I think that the real reason why numeric_limits<complex<> > is
left unspecialized is because you can't have a meaningful
specialization, without knowing the implementation. And the
implementation is not mandated. It can be either x+iy (fast addition,
slow sqrt) or r*exp(i*\theta) (slow addition, fast sqrt), or anything
else in between.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.

Eric Gindrup

unread,
Apr 15, 1997, 3:00:00 AM4/15/97
to

Brian Parker wrote:
> "Bradd W. Szonye" <bra...@concentric.net> wrote:
[...]
> I don't think that being "linear" or ordered is a requirement for
> scalars. In linear algebra, scalars are things used as scalars (or is
> that too tautological :-) ) i.e. numbers that are used in that role in
> a linear space.
>

Lambaste << on;
I find three definitions of scalar in use:
1) A quantity with magnitude but not direction.
2) An element of the array constituting a matrix or of the field over
which a vector space is defined.
3) an element of the ring over which a commutative group is a module.

The third is probably tangential to any discussion in this newsgroup.
The second does not address the difficulty presentd in this thread.
The first is much more useful. numeric_limits<> seems mostly
targetted at the first definition.



>> Generally, there is a one-to-one mapping between a scalar type and
>> either real numbers or integers; there is no such mapping for
>> complex numbers.
>

> I don't think this is accurate, for example a finite field could be
> used as a scalar but it is certainly not one-one with R or Z (in fact,
> Z is not a field and so couldn't be used as a scalar)

1-to-1 does not imply onto. There exists a 1-to-1 map from {1} to
Z: let a be an element of Z. Construct f = {{1,{1,a}}}, i.e. f
maps 1 to a. f is 1-to-1 (injective). f is not onto (surjective).

>> From a practical standpoint: the definition of numeric_limits<>
>> isn't well-suited to representing the traits of non-linear numbers.
>> It's concerned with minima, maxima, and granularity, which are all
>> concepts that do not translate well into two-dimensional numbers.
>
> I think this is the crux of the matter, numeric_limits is only useful

> for ordered sets and complex is not ordered; whether the type can be
> used as a scalar is irrelevant.
[...]
> .Brian parker (bpa...@gil.com.au)

What makes you say that C has no linear ordering? To use a big hammer,
The Axiom of Choice (eventually) allows the construction of a total
order on C. That order is just very strange (and has not been
explicitly constructed by anyone).
-- Eric Gindrup ! gin...@okway.okstate.edu

James Kanze

unread,
Apr 16, 1997, 3:00:00 AM4/16/97
to

Oleg Zabluda <zab...@math.psu.edu> writes:

|> Arithmetic types (_basic.fundamental_), enumeration types,
|> pointer types, and pointer to member types (_basic.compound_),
|> and cv-qualified versions of these types (_basic.type.qualifier_)

|> are collectively called scalar types.
|>
|> I think that the real reason why numeric_limits<complex<> > is
|> left unspecialized is because you can't have a meaningful
|> specialization, without knowing the implementation. And the
|> implementation is not mandated. It can be either x+iy (fast
addition,
|> slow sqrt) or r*exp(i*\theta) (slow addition, fast sqrt), or
anything
|> else in between.

Even if you know the implementation: complex numbers are unordered, so
what do max and min mean (for example)?

--
James Kanze home: ka...@gabi-soft.fr +33 (0)1 39 55 85
62
office: ka...@vx.cit.alcatel.fr +33 (0)1 69 63 14
54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles
France
-- Conseils en informatique industrielle --

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Brian Parker

unread,
Apr 16, 1997, 3:00:00 AM4/16/97
to

Eric Gindrup <gin...@okway.okstate.edu> wrote:

>Brian Parker wrote:
>> "Bradd W. Szonye" <bra...@concentric.net> wrote:
>[...]
>> I don't think that being "linear" or ordered is a requirement for
>> scalars. In linear algebra, scalars are things used as scalars (or is
>> that too tautological :-) ) i.e. numbers that are used in that role in
>> a linear space.
>>

>Lambaste << on;
>I find three definitions of scalar in use:
>1) A quantity with magnitude but not direction.
>2) An element of the array constituting a matrix or of the field over
> which a vector space is defined.
>3) an element of the ring over which a commutative group is a module.

>The third is probably tangential to any discussion in this newsgroup.
>The second does not address the difficulty presentd in this thread.
>The first is much more useful. numeric_limits<> seems mostly
>targetted at the first definition.

Yes, but this thread started with the linear algebraic definitions
being used as an example where the term "non-scalar" excludes complex.
The intent of the draft (as opposed to its current definition) is
apparently to disallow users from adding specialisations to
numeric_limits for "non-scalars" and if so the term needs to have an
unequivocal definition. (As was pointed out elsewhere in this thread,
the draft specifies "scalar types" to mean arithmetic, enumeration and
pointer types, so another definition of "non-scalar" would be "none of
these", but that is not too helpful as it would again exclude all
user-defined types.)

I would prefer to simply see the sentence-
"The member is_specialized makes it possible to distinguish between
fundamental types which have specialisations, and non-scalar types,
which do not."
removed from the draft and leave it up to the individual to decide if
their user-defined type is appropriate for numeric_limits
specialisation.

>>> Generally, there is a one-to-one mapping between a scalar type and
>>> either real numbers or integers; there is no such mapping for
>>> complex numbers.
>>
>> I don't think this is accurate, for example a finite field could be
>> used as a scalar but it is certainly not one-one with R or Z (in fact,
>> Z is not a field and so couldn't be used as a scalar)

>1-to-1 does not imply onto. There exists a 1-to-1 map from {1} to
>Z: let a be an element of Z. Construct f = {{1,{1,a}}}, i.e. f
>maps 1 to a. f is 1-to-1 (injective). f is not onto (surjective).

Oops. In the context, I read the above as meaning one-to-one
correspondence with real or integer, but of course you are right.

>>> From a practical standpoint: the definition of numeric_limits<>
>>> isn't well-suited to representing the traits of non-linear numbers.
>>> It's concerned with minima, maxima, and granularity, which are all
>>> concepts that do not translate well into two-dimensional numbers.
>>
>> I think this is the crux of the matter, numeric_limits is only useful
>> for ordered sets and complex is not ordered; whether the type can be
>> used as a scalar is irrelevant.

>What makes you say that C has no linear ordering? To use a big hammer,


>The Axiom of Choice (eventually) allows the construction of a total
>order on C. That order is just very strange (and has not been
>explicitly constructed by anyone).
> -- Eric Gindrup ! gin...@okway.okstate.edu

To use a smaller hammer, for an actual implementation of complex one
could always define a lexicographical ordering of its raw bytes. I
was thinking of the usual ordering as defined by operator< etc. in the
above (though you have piqued my interest in set theory here).

Thanks for your comments,
Brian Parker (bpa...@gil.com.au)

Oleg Zabluda

unread,
Apr 16, 1997, 3:00:00 AM4/16/97
to

Oleg Zabluda <zab...@math.psu.edu> wrote:
: Brian Parker <bpa...@gil.com.au> wrote:
: : I don't think this is accurate, for example a finite field could be

: : used as a scalar but it is certainly not one-one with R or Z (in fact,
: : Z is not a field and so couldn't be used as a scalar)

: : (real mathematicians in the audience also feel free to lambast me on


: : any of the preceeding points).

: I am a real mathematician, and you are right. In mathematics a
: "scalar" is always used in conjunction with a "vector". Vectors
: are elements of a vector space. Vector space is a module over
: a field (any field). A is a module over B means that one must be
: able to multiply elements of A by elements of B. Being a field
: means that one must be able to add, subtract, multiply and divide
: it's elements.

Sorry, it occurred to me only now, that C++ provides a perfect example
of that:

vector<complex<double> > is a vector space over complex<double>.

Not that it has anything to do with the topic :-).

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

David A. Cuthbert

unread,
Apr 16, 1997, 3:00:00 AM4/16/97
to

James Kanze <james-alb...@vx.cit.alcatel.fr> wrote:
>Even if you know the implementation: complex numbers are unordered, so
>what do max and min mean (for example)?

As I mentioned earlier, min and max don't have a meaning on complex
numbers, but a complex class *should* define min and max (and epsilon)
for the elements of (at least) the two most common representations:
a + jb and r exp(jw).

This doesn't fit in numeric_limits (though the implementations of
these functions would and should use the numeric_limits class). That
doesn't mean it shouldn't be defined.

I don't know if the complex class in the standard does this (I don't
do much numeric computation in C++ anymore unless it involves
simulations, and then I use my own complex class, anyway). If it
doesn't, it probably should.


--
David A. Cuthbert (henry.ece.cmu.edu!dacut)
Graduate Student, Electrical and Computer Engineering
Data Storage Systems Center, Carnegie Mellon University

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

James Kanze

unread,
Apr 17, 1997, 3:00:00 AM4/17/97
to

bpa...@gil.com.au (Brian Parker) writes:

|> I would prefer to simply see the sentence-
|> "The member is_specialized makes it possible to distinguish between
|> fundamental types which have specialisations, and non-scalar types,
|> which do not."
|> removed from the draft and leave it up to the individual to decide if
|> their user-defined type is appropriate for numeric_limits
|> specialisation.

I would certainly agree that it is up to the user with regards to his
types. But the draft should specify which of the types defined in the
draft have specializations. I think that this was the intent of the
passage in question, although I don't think that it does a very good job
as fulfilling its intent.

--
James Kanze home: ka...@gabi-soft.fr +33 (0)1 39 55 85 62
office: ka...@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Oleg Zabluda

unread,
Apr 17, 1997, 3:00:00 AM4/17/97
to

James Kanze <james-alb...@vx.cit.alcatel.fr> wrote:
: Oleg Zabluda <zab...@math.psu.edu> writes:

: |> I think that the real reason why numeric_limits<complex<> > is


: |> left unspecialized is because you can't have a meaningful
: |> specialization, without knowing the implementation. And the
: |> implementation is not mandated. It can be either x+iy (fast
: |> addition,
: |> slow sqrt) or r*exp(i*\theta) (slow addition, fast sqrt), or
: |> anything
: |> else in between.

: Even if you know the implementation: complex numbers are unordered, so


: what do max and min mean (for example)?

Well, if we know that the implementation of complex<double> is
x+iy, where x and y are double, then max would mean maximal value
of x = maximal value of y.

If we know that the implementation is r*exp(i*\theta), max will be
the maximal value of r. (minimal value or r is 0).

We are not concerned that out min and max have mathemetical sense,
I think. We just want to extract as much info as we can and make
it in a way that we don't have to change the program if we replace
complex<double> with complex<long double>.

Note that, strictly speaking, you also must know the implementation
of arithmetical operations on complex<double> to be able to use
the above mentioned info for anything useful.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.

Eric Gindrup

unread,
Apr 17, 1997, 3:00:00 AM4/17/97
to

Brian Parker wrote:
[math stuff deleted...]

> The intent of the draft (as opposed to its current definition) is
> apparently to disallow users from adding specialisations to
> numeric_limits for "non-scalars" and if so the term needs to have an
> unequivocal definition. (As was pointed out elsewhere in this thread,
> the draft specifies "scalar types" to mean arithmetic, enumeration and
> pointer types, so another definition of "non-scalar" would be "none of
> these", but that is not too helpful as it would again exclude all
> user-defined types.)
>
> I would prefer to simply see the sentence-
> "The member is_specialized makes it possible to distinguish between
> fundamental types which have specialisations, and non-scalar types,
> which do not."
> removed from the draft and leave it up to the individual to decide if
> their user-defined type is appropriate for numeric_limits
> specialisation.
[more math stuff deleted...]

>>>> From a practical standpoint: the definition of numeric_limits<>
>>>> isn't well-suited to representing the traits of non-linear numbers.
>>>> It's concerned with minima, maxima, and granularity, which are all
>>>> concepts that do not translate well into two-dimensional numbers.
[further math stuff deleted...]

> Thanks for your comments,
> Brian Parker (bpa...@gil.com.au)

Well, why not just have the user-defined types for which parts of
numeric_limits<> is reasonably defined publicly inherit those members
of the template that make sense (and privately inherit those that
don't). Then the end-user doesn't even have to know what type the
thing is, it can just ask directly...
if(foo.max < bar)...


-- Eric Gindrup ! gin...@okway.okstate.edu

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Todd Veldhuizen

unread,
Apr 19, 1997, 3:00:00 AM4/19/97
to

I'm to blame for this bit of the standard, so I might be able to
clarify the purpose of numeric_limits<T>.

The intent of numeric_limits<T> is to wrap <float.h> and <limits.h>
so that templates can access the numeric properties of their
parameter(s). In addition, many newer fields were added to
help C++ conform to the language independent arithmetic (LIA)
standard.

Specializations are not provided for complex<T> because the
members of numeric_limits<complex<T> > would not have meaningful
or unambiguous values. If you need to know e.g. the machine epsilon
for the underlying type used by complex<T>, you can obtain this from
numeric_limits<T>. One might argue that the machine epsilon of
complex<double> should be (DBL_EPSILON,0) or (DBL_EPSILON,DBL_EPSILON),
but the point is that the choice isn't unambiguous.

It *was* intended that numeric_limits<T> be specializable for
user-defined types. This supports using numerical types from
one library (e.g. an extended precision floating point type) with
generic algorithms from another (e.g. integration). It sounds
to me like the wording in the standard is incorrect, unless
the standards committee uncovered compelling reasons for
restricting specializations to intrinsic types.

If you need something more elaborate than numeric_limits<T>,
then you can construct your own traits classes which build
upon it. For example, if you *need* specializations of
complex<T>, you can create a traits class which inherits from
numeric_limits<T> and specialize it yourself.

I'm obliged to point out that John Barton and Lee Nackman
originated the idea of a numerical properties traits
class and published it in their book, "Scientific and
Engineering C++". I submitted the numeric_limits<T>
proposal before I'd noticed the similar class in
their book, despite the uncanny resemblance between
the two.

If you want to do something *really* elaborate, you can
probably construct a traits class which will map any type with
an underlying numeric representation onto the appropriate
numeric_limits<T>. For example, such a traits class would
map list<valarray<complex<double> > > onto numeric_limits<double>.

You'd use something with this kind of structure:

template<class T>
struct underlying_numeric_traits {
typedef underlying_numeric_traits<typename T::T> traits;
};

with appropriate specializations.

Cheers,
Todd
--
Todd Veldhuizen to...@cybervision.com
Homepage: http://monet.uwaterloo.ca/~tveldhui/

--
Todd Veldhuizen tvel...@monet.uwaterloo.ca
Homepage: http://monet.uwaterloo.ca/~tveldhui/

Brian Parker

unread,
Apr 19, 1997, 3:00:00 AM4/19/97
to

James Kanze <james-alb...@vx.cit.alcatel.fr> wrote:

>bpa...@gil.com.au (Brian Parker) writes:

>|> I would prefer to simply see the sentence-
>|> "The member is_specialized makes it possible to distinguish between
>|> fundamental types which have specialisations, and non-scalar types,
>|> which do not."
>|> removed from the draft and leave it up to the individual to decide if
>|> their user-defined type is appropriate for numeric_limits
>|> specialisation.

>I would certainly agree that it is up to the user with regards to his


>types. But the draft should specify which of the types defined in the
>draft have specializations. I think that this was the intent of the
>passage in question, although I don't think that it does a very good job
>as fulfilling its intent.

The draft already specifies that the fundamental types have
specialisations. I don't think it needs to explicitly forbid other
types (even those in the draft library) from having specialisations;
any additional specialisations would simply be non-standard extensions
provided by the implementor.

,Brian Parker (bpa...@gil.com.au)

Brian Parker

unread,
Apr 19, 1997, 3:00:00 AM4/19/97
to

Eric Gindrup <gin...@okway.okstate.edu> wrote:

>...


>Well, why not just have the user-defined types for which parts of
>numeric_limits<> is reasonably defined publicly inherit those members
>of the template that make sense (and privately inherit those that
>don't). Then the end-user doesn't even have to know what type the
>thing is, it can just ask directly...
> if(foo.max < bar)...
> -- Eric Gindrup ! gin...@okway.okstate.edu

A disadvantage of that scheme is that there are then two different
ways of accessing the information- through a traits class for the
fundamental types, and via member access for user-defined types, which
would be less convenient for generic (template) functions.

James Youngman

unread,
Apr 21, 1997, 3:00:00 AM4/21/97
to

In article <5jbbv8$a...@netlab.cs.rpi.edu>, bpa...@gil.com.au says...

>The draft already specifies that the fundamental types have
>specialisations. I don't think it needs to explicitly forbid other
>types (even those in the draft library) from having specialisations;
>any additional specialisations would simply be non-standard extensions
>provided by the implementor.
>
>,Brian Parker (bpa...@gil.com.au)

I think that what this phrasing in the draft was doing was forcing all
specializations to provide an is_specialized() that returns nonzero. I believe
that to have been the intent, but it looks as if the wording was confusing.

--
James Youngman VG Gas Analysis Systems The trouble with the rat-race
Before sending advertising material, read is, even if you win, you're
http://www.law.cornell.edu/uscode/47/227.html still a rat.

0 new messages