472,991 Members | 2,848 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

template computed alternative to numeric_limits<T>


The spirit of this arguably pointless exercise, is that the
numeric_limits<T> class could be replaced with a totally generic
template of compile-time, template computed constants.

The problem is that it takes a *long* time to compile and the "long
double" version instantiates so many classes that gcc runs out of memory
on my 1 gig machine !

So the question is - is there a simple way to reduce the number of
template instantiations from O(N) to O(logN) ?

#include <iostream>
#include <limits>
template <typename T, int N>
struct pow_m
{
static const T value =
( ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 ) ) -
static_cast<T>( 1 )
== ( pow_m<T, N-1>::value * 2 )
? ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 )
: ( pow_m<T, N-1>::value * 2 );

static const T valuep1 = ( value * 2 );
};

template <typename T>
struct pow_m<T, 0>
{
static const T value = static_cast<T>( 1 );
static const T valuep1 = ( value * 2 ) + static_cast<T>( 1 );
};

template <typename T, int N, bool v> struct max_f;

template <typename T, int N>
struct max_f<T,N,true>
{
static const T max_value = pow_m<T,N-1>::value;

static const int max_exponent = N-1;
};

template <typename T, int N, bool v>
struct max_f : max_f<T, N+1, pow_m<T, N+1>::value == pow_m<T,
N+1>::valuep1 >
{
};

template <typename T, int N>
struct pow_nm
{
static const T value =
( ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 ) ) -
static_cast<T>( -1 )
== ( pow_nm<T, N-1>::value * 2 )
? ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 )
: ( pow_nm<T, N-1>::value * 2 );

static const T valuep1 = ( value * 2 );
};

template <typename T>
struct pow_nm<T, 0>
{
static const T value = static_cast<T>( -1 );
static const T valuep1 = ( value * 2 ) + static_cast<T>( -1 );
};

template <typename T, int N, bool v> struct max_nm;

template <typename T, int N>
struct max_nm<T,N,true>
{
static const T max_value = pow_nm<T,N-1>::value;

static const int max_exponent = N-1;
};

template <typename T, int N, bool v>
struct max_nm : max_nm<T, N+1, pow_nm<T, N+1>::value == pow_nm<T,
N+1>::valuep1 >
{
};

template<typename T>
struct max_limit
{
static const int max_exponent = max_f<T,0,false>::max_exponent;
static const T max_value = max_f<T,0,false>::max_value;

static const int neg_max_exponent = max_nm<T,0,false>::max_exponent;
static const T neg_max_value = max_nm<T,0,false>::max_value;

};

int main()
{
std::cout << "Positive maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::max_exponent << "\n";
std::cout << max_limit< float >::max_value << "\n";

std::cout << "Double\n";
std::cout << max_limit< double >::max_exponent << "\n";
std::cout << max_limit< double >::max_value << "\n";

std::cout << "limits max says " <<
std::numeric_limits<double>::max() << "\n";
std::cout << "limits/template diff " << (
std::numeric_limits<double>::max() - max_limit< double >::max_value ) <<
"\n";

std::cout << "Negative maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::neg_max_exponent << "\n";
std::cout << max_limit< float >::neg_max_value << "\n";

std::cout << "Double\n";
std::cout << max_limit< double >::neg_max_exponent << "\n";
std::cout << max_limit< double >::neg_max_value << "\n";
/*
std::cout << "Long Double\n";
std::cout << max_limit< long double >::max_exponent << "\n";
std::cout << max_limit< long double >::max_value << "\n";
*/
}
Jul 22 '05 #1
5 2114

"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:O9********************@speakeasy.net...

The spirit of this arguably pointless exercise, is that the
numeric_limits<T> class could be replaced with a totally generic
template of compile-time, template computed constants.

The problem is that it takes a *long* time to compile and the "long

[snip]

I don't know anything about templates (yet) but this DMC
(Digital Mars) compiler complains that static members should
initialised outside of the structures. I may not be the smartest
of C++ programers but I seem to remember that this is also
the way with 'ordinary' classes ;-)

Alan

Jul 22 '05 #2
Alan wrote:
"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:O9********************@speakeasy.net...
The spirit of this arguably pointless exercise, is that the
numeric_limits<T> class could be replaced with a totally generic
template of compile-time, template computed constants.

The problem is that it takes a *long* time to compile and the "long


[snip]

I don't know anything about templates (yet) but this DMC
(Digital Mars) compiler complains that static members should
initialised outside of the structures. I may not be the smartest
of C++ programers but I seem to remember that this is also
the way with 'ordinary' classes ;-)


OK - here is a version that might work for you:
#include <iostream>
#include <limits>
template <typename T, int N>
struct pow_m
{
static const T value;

static const T valuep1;
};

template <typename T, int N>
const T pow_m<T,N>::value =
( ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 ) ) -
static_cast<T>( 1 )
== ( pow_m<T, N-1>::value * 2 )
? ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 )
: ( pow_m<T, N-1>::value * 2 );

template <typename T, int N>
const T pow_m<T,N>::valuep1 = ( value * 2 );

template <typename T>
struct pow_m<T, 0>
{
static const T value;
static const T valuep1;
};

template <typename T>
const T pow_m<T, 0>::value = static_cast<T>( 1 );
template <typename T>
const T pow_m<T, 0>::valuep1 = ( value * 2 ) + static_cast<T>( 1 );

template <typename T, int N, bool v> struct max_f;

template <typename T, int N>
struct max_f<T,N,true>
{
static const T max_value;

static const int max_exponent;
};
template <typename T, int N>
const T max_f<T,N,true>::max_value = pow_m<T,N-1>::value;

template <typename T, int N>
const int max_f<T,N,true>::max_exponent = N-1;

template <typename T, int N>
struct eval_f
{
static const bool at_limit = ( pow_m<T, N+1>::value == pow_m<T,
N+1>::valuep1 );
};

template <typename T, int N, bool v>
struct max_f : max_f<T, N+1, eval_f<T,N>::at_limit >
{
};

template <typename T, int N>
struct pow_nm
{
static const T value;

static const T valuep1;

};

template <typename T, int N>
const T pow_nm<T,N>::value =
( ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 ) ) -
static_cast<T>( -1 )
== ( pow_nm<T, N-1>::value * 2 )
? ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 )
: ( pow_nm<T, N-1>::value * 2 );

template <typename T, int N>
const T pow_nm<T,N>::valuep1 = ( value * 2 );

template <typename T>
struct pow_nm<T, 0>
{
static const T value;
static const T valuep1;
};
template <typename T>
const T pow_nm<T, 0>::value = static_cast<T>( -1 );
template <typename T>
const T pow_nm<T, 0>::valuep1 = ( value * 2 ) + static_cast<T>( -1 );

template <typename T, int N, bool v> struct max_nm;

template <typename T, int N>
struct max_nm<T,N,true>
{
static const T max_value;

static const int max_exponent;
};

template <typename T, int N>
const T max_nm<T,N,true>::max_value = pow_nm<T,N-1>::value;

template <typename T, int N>
const int max_nm<T,N,true>::max_exponent = N-1;

template <typename T, int N>
struct eval_nm
{
static const bool at_limit = ( pow_nm<T, N+1>::value == pow_nm<T,
N+1>::valuep1 );
};

template <typename T, int N, bool v>
struct max_nm : max_nm<T, N+1, eval_nm<T,N>::at_limit >
{
};

template<typename T>
struct max_limit
{
static const int max_exponent;
static const T max_value;

static const int neg_max_exponent;
static const T neg_max_value;

};

template<typename T>
const int max_limit<T>::max_exponent = max_f<T,0,false>::max_exponent;
template<typename T>
const T max_limit<T>::max_value = max_f<T,0,false>::max_value;

template<typename T>
const int max_limit<T>::neg_max_exponent =
max_nm<T,0,false>::max_exponent;
template<typename T>
const T max_limit<T>::neg_max_value = max_nm<T,0,false>::max_value;

int main()
{
std::cout << "Positive maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::max_exponent << "\n";
std::cout << max_limit< float >::max_value << "\n";

std::cout << "Double\n";
std::cout << max_limit< double >::max_exponent << "\n";
std::cout << max_limit< double >::max_value << "\n";

std::cout << "limits max says " <<
std::numeric_limits<double>::max() << "\n";
std::cout << "limits/template diff " << (
std::numeric_limits<double>::max() - max_limit< double >::max_value ) <<
"\n";

std::cout << "Negative maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::neg_max_exponent << "\n";
std::cout << max_limit< float >::neg_max_value << "\n";

std::cout << "Double\n";
std::cout << max_limit< double >::neg_max_exponent << "\n";
std::cout << max_limit< double >::neg_max_value << "\n";
/*
std::cout << "Long Double\n";
std::cout << max_limit< long double >::max_exponent << "\n";
std::cout << max_limit< long double >::max_value << "\n";
*/
}
Jul 22 '05 #3

"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:J7********************@speakeasy.net...
Alan wrote:
"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:O9********************@speakeasy.net...
The spirit of this arguably pointless exercise, is that the
numeric_limits<T> class could be replaced with a totally generic
template of compile-time, template computed constants.

The problem is that it takes a *long* time to compile and the "long
[snip]

I don't know anything about templates (yet) but this DMC
(Digital Mars) compiler complains that static members should
initialised outside of the structures. I may not be the smartest
of C++ programers but I seem to remember that this is also
the way with 'ordinary' classes ;-)


OK - here is a version that might work for you:
#include <iostream>
#include <limits>
template <typename T, int N>
struct pow_m
{
static const T value;

static const T valuep1;
};

template <typename T, int N>
const T pow_m<T,N>::value =
( ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 ) ) -
static_cast<T>( 1 )
== ( pow_m<T, N-1>::value * 2 )
? ( pow_m<T, N-1>::value * 2 ) + static_cast<T>( 1 )
: ( pow_m<T, N-1>::value * 2 );

template <typename T, int N>
const T pow_m<T,N>::valuep1 = ( value * 2 );

template <typename T>
struct pow_m<T, 0>
{
static const T value;
static const T valuep1;
};

template <typename T>
const T pow_m<T, 0>::value = static_cast<T>( 1 );
template <typename T>
const T pow_m<T, 0>::valuep1 = ( value * 2 ) + static_cast<T>( 1 );

template <typename T, int N, bool v> struct max_f;

template <typename T, int N>
struct max_f<T,N,true>
{
static const T max_value;

static const int max_exponent;
};
template <typename T, int N>
const T max_f<T,N,true>::max_value = pow_m<T,N-1>::value;

template <typename T, int N>
const int max_f<T,N,true>::max_exponent = N-1;

template <typename T, int N>
struct eval_f
{
static const bool at_limit = ( pow_m<T, N+1>::value == pow_m<T,
N+1>::valuep1 );
};

template <typename T, int N, bool v>
struct max_f : max_f<T, N+1, eval_f<T,N>::at_limit >
{
};

template <typename T, int N>
struct pow_nm
{
static const T value;

static const T valuep1;

};

template <typename T, int N>
const T pow_nm<T,N>::value =
( ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 ) ) -
static_cast<T>( -1 )
== ( pow_nm<T, N-1>::value * 2 )
? ( pow_nm<T, N-1>::value * 2 ) + static_cast<T>( -1 )
: ( pow_nm<T, N-1>::value * 2 );

template <typename T, int N>
const T pow_nm<T,N>::valuep1 = ( value * 2 );

template <typename T>
struct pow_nm<T, 0>
{
static const T value;
static const T valuep1;
};
template <typename T>
const T pow_nm<T, 0>::value = static_cast<T>( -1 );
template <typename T>
const T pow_nm<T, 0>::valuep1 = ( value * 2 ) + static_cast<T>( -1 );

template <typename T, int N, bool v> struct max_nm;

template <typename T, int N>
struct max_nm<T,N,true>
{
static const T max_value;

static const int max_exponent;
};

template <typename T, int N>
const T max_nm<T,N,true>::max_value = pow_nm<T,N-1>::value;

template <typename T, int N>
const int max_nm<T,N,true>::max_exponent = N-1;

template <typename T, int N>
struct eval_nm
{
static const bool at_limit = ( pow_nm<T, N+1>::value == pow_nm<T,
N+1>::valuep1 );
};

template <typename T, int N, bool v>
struct max_nm : max_nm<T, N+1, eval_nm<T,N>::at_limit >
{
};

template<typename T>
struct max_limit
{
static const int max_exponent;
static const T max_value;

static const int neg_max_exponent;
static const T neg_max_value;

};

template<typename T>
const int max_limit<T>::max_exponent = max_f<T,0,false>::max_exponent;
template<typename T>
const T max_limit<T>::max_value = max_f<T,0,false>::max_value;

template<typename T>
const int max_limit<T>::neg_max_exponent =
max_nm<T,0,false>::max_exponent;
template<typename T>
const T max_limit<T>::neg_max_value = max_nm<T,0,false>::max_value;

int main()
{
std::cout << "Positive maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::max_exponent << "\n";
std::cout << max_limit< float >::max_value << "\n";

std::cout << "Double\n";
std::cout << max_limit< double >::max_exponent << "\n";
std::cout << max_limit< double >::max_value << "\n";

std::cout << "limits max says " <<
std::numeric_limits<double>::max() << "\n";
std::cout << "limits/template diff " <<

std::numeric_limits<double>::max() - max_limit< double >::max_value ) <<
"\n";

std::cout << "Negative maximum\n";
std::cout << "Float\n";
std::cout << max_limit< float >::neg_max_exponent << "\n";
std::cout << max_limit< float >::neg_max_value << "\n";

std::cout << "Double\n";
std::cout << max_limit< double >::neg_max_exponent << "\n";
std::cout << max_limit< double >::neg_max_value << "\n";

std::cout << "Long Double\n";
std::cout << max_limit< long double >::max_exponent << "\n";
std::cout << max_limit< long double >::max_value << "\n";

}


Complains:
Line 55: in-class initializer for const at_limit not constant
Line 59: constant initializer expected

Alan
Jul 22 '05 #4
Alan wrote:
Complains:
Line 55: in-class initializer for const at_limit not constant
Line 59: constant initializer expected


Now the question is, it that legal ?

GCC compiles it just fine.
Jul 22 '05 #5

"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:7b********************@speakeasy.net...
Alan wrote:
Complains:
Line 55: in-class initializer for const at_limit not constant
Line 59: constant initializer expected
Now the question is, it that legal ?

GCC compiles it just fine.


I'm not the person to answer your question.

But does it still "takes a *long* time to compile and the "long double"
version instantiates so many classes that gcc runs out of memory
on my 1 gig machine !" ?
The problem is that it takes a *long* time to compile and the "long
double" version instantiates so many classes that gcc runs out of memory
on my 1 gig machine !



Jul 22 '05 #6

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

Similar topics

2
by: Eshrath | last post by:
Hi, What I am trying to do: ======================= I need to form a table in html using the xsl but the table that is formed is quite long and cannot be viewed in our application. So we are...
8
by: Dave | last post by:
Hello all, Is is allowable for me to specialize numeric_limits<> for my own numeric type? Does this violate any sort of rule against mucking with std? Thanks, Dave
2
by: Steve | last post by:
I don't get it. In Codewarrior for Mac OS 9.4, numeric_limits<unsigned char>::digits10 == 2. Unless I don't understand it properly (most likely!) I thought digits10 was supposed to represent...
14
by: SoilMan | last post by:
Consider the following: class xyz { public: template <typename T> void foo(T x) { cout << "foo<T> " << x << endl; }
4
by: Simon | last post by:
Hi, I am trying to create a round kind of function, (to round float and double to int). In the H file I can do the following with not too much trouble... // #include <limits> #include...
4
by: Grizlyk | last post by:
Hello. Why were base class "typedefs" hidden by template<and explicit usage of them does not work too? Try open only one of the lines in the example below //using Tparent::Tptr; //typedef...
3
by: George2 | last post by:
Hello everyone, I sometimes saw code with template<and followed by a class definition, like, template<class { // class definition
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

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.