473,405 Members | 2,379 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Expect ArithmeticType to have limits?


Let's say we want to write a function which calculates the force which
earth's gravity exerts on an object of particular mass at sea level. We
could start off with:

unsigned CalcForce(unsigned const mass)
{
return mass * 9.81; /* Let's ignore the rounding-down */
}

Of course though, C++ has many built-in arithmetic types; we could as
easily have written it as:

double CalcForce(double const mass)
{
return mass * 9.81;
}

or:

long unsigned CalcForce(long unsigned const mass)
{
return mass * 9.81;
}

So this might lead us to write a template function which can deal with any
arithmetic type. We might start off with:

template<class T>
T CalcForce(T const mass)
{
return mass * 9.81;
}

The problem with this, however, is that it is TOO generic -- it could be
passed anything from a pointer to an std::string! In an attempt to restrict
the possibilities, maybe we could try:

#define COMPASS /* Compile-time assertion */

#include <limits>

template<class T>
T CalcForce(T const mass)
{
COMPASS(std::numeric_limits<T>::is_specialized);

return mass * 9.81;
}

Do you think this is a wise way to write a generic function which deals
with numbers?

Lastly, let's say that we want this function to work with user-defined
arithmetic types also, such as a BigNum library. Should any such classes be
expected to have a specialisation of "numeric_limits"?

--

Frederick Gotham
Sep 23 '06 #1
4 1509
Frederick Gotham wrote:
So this might lead us to write a template function which can deal with any
arithmetic type. We might start off with:

template<class T>
T CalcForce(T const mass)
{
return mass * 9.81;
}

The problem with this, however, is that it is TOO generic -- it could be
passed anything from a pointer to an std::string! In an attempt to
restrict the possibilities, maybe we could try:
You can't pass anything. If you specialize it for anything that has not an
adequate operator * it will not compile. The problem is that the error
message can be difficult to understand, but there are ways to work around
that. There is paper about this in Stroustrup's web, for example.
template<class T>
T CalcForce(T const mass)
{
COMPASS(std::numeric_limits<T>::is_specialized);

return mass * 9.81;
}

Do you think this is a wise way to write a generic function which deals
with numbers?

Lastly, let's say that we want this function to work with user-defined
arithmetic types also, such as a BigNum library. Should any such classes
be expected to have a specialisation of "numeric_limits"?
If you write code like this you are effectively expecting it. I see one
problem with this approach. One programmer may want to use your function
with a third part BigNum class that does not have that specialization. No
problem, they say, I can write it on my own. Later, a new version of the
BigNum class is released, and now it has the specialization of
numeric_limits. The program must be adapted, or must use conditional code
to be able to compile with any BigNum version.

IMO is more practical to check only for what you need: the availability of
an adequate operator *, in this case.

--
Salu2
Sep 23 '06 #2
Frederick Gotham wrote:
>
The problem with this, however, is that it is TOO generic -- it could be
passed anything from a pointer to an std::string! In an attempt to restrict
the possibilities, maybe we could try:

#define COMPASS /* Compile-time assertion */

#include <limits>

template<class T>
T CalcForce(T const mass)
{
COMPASS(std::numeric_limits<T>::is_specialized);

return mass * 9.81;
}
Decide which numeric types you're using in your program and write
functions that take those types. Supporting two or three types doesn't
require templates. Further, getting good results from numeric
computations means writing type-specific code -- it varies depending on
the details of the type. You can't, in general, write it generically.

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Sep 23 '06 #3
Pete Becker posted:
Decide which numeric types you're using in your program and write
functions that take those types.

The point is to write portable code which can be used for all sorts of
different integer types, including the linkes of:

__int256 a,b = 34,c;

a = CalcForce(b);

Supporting two or three types doesn't require templates.

The point is to support *all* arithmetic types, including user-defined
ones.

Further, getting good results from numeric computations means writing
type-specific code -- it varies depending on the details of the type.
You can't, in general, write it generically.

I write arithmetic generic code all the time -- all you need is a robust
understanding of integer promotion and conversion.

--

Frederick Gotham
Sep 23 '06 #4
Frederick Gotham wrote:
Pete Becker posted:
>Decide which numeric types you're using in your program and write
functions that take those types.


The point is to write portable code which can be used for all sorts of
different integer types, including the linkes of:

__int256 a,b = 34,c;

a = CalcForce(b);
Why?
>
>Supporting two or three types doesn't require templates.


The point is to support *all* arithmetic types, including user-defined
ones.
Again, why?
>
>Further, getting good results from numeric computations means writing
type-specific code -- it varies depending on the details of the type.
You can't, in general, write it generically.


I write arithmetic generic code all the time -- all you need is a robust
understanding of integer promotion and conversion.
But your example function only makes sense for floating-point types.
Even if you want to throw in int or long, why in the world do you need
to calculate forces for char, unsigned char, and signed char?

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Sep 23 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
by: Maurice LING | last post by:
Hi, I think I've hit a system limit in python when I try to construct a list of 200,000 elements. My error is malloc: vm_allocate (size = 2400256) failed...... Just wondering is this...
4
by: platho | last post by:
Hello, I bounced into the max 25 columns index limits on DB2 v7.2 on NT. Is this still so in other operating systems or in v8 ? Are there plans to change this in the future ? Any workarounds...
16
by: Mark Bruno | last post by:
Hey, I'm learning about the limits header, and I don't understand one snippit of code. If I code: #include <limits.h> #include <stdio.h> int main() { printf("Smallest signed long long:...
37
by: Carol Depore | last post by:
How do I determine the maximum array size? For example, int a works, but a does not (run time error). Thank you.
158
by: madhawi | last post by:
This question is occur in interview. Please help me.
88
by: santosh | last post by:
Hello all, In K&R2 one exercise asks the reader to compute and print the limits for the basic integer types. This is trivial for unsigned types. But is it possible for signed types without...
7
by: copx | last post by:
Do the standards say anything about size limits for string literals (min size, max size)? I want to know this to make sure that my code is portable. The program in question is ANSI C89, but I would...
13
by: Josip | last post by:
I'm trying to limit a value stored by object (either int or float): class Limited(object): def __init__(self, value, min, max): self.min, self.max = min, max self.n = value def...
44
by: vippstar | last post by:
n1256.pdf (C99 TC3), 5.2.4.1 Translation limits p1 says: Does that mean that *any* program using an array of two or more elements other than char is allowed to be rejected by an implementation?...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.