This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
numeric_limits<>: an attempt
- To: egcs at cygnus dot com
- Subject: numeric_limits<>: an attempt
- From: Max Lawson <mlawson at drfmc dot ceng dot cea dot fr>
- Date: Fri, 12 Dec 1997 16:37:05 +0100
- Reply-To: egcs at cygnus dot com
----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 14
hello,
I've asked if sbdy is working on the numeric_limis<> class. In the abscence
of response, I've tryed to implement this class and its specializations using
the Dec96-WP. I'm using the C macros to define the requiered values.
I'm giving up now cause I don't know where to find some macros :(
So, the implementation below is far from being complete... If a guru
can have a look ;-)
Best regards, Max
I've attached the <limits> file I've obtained and the Perl script i'm using
to build them.
----------
X-Sun-Data-Type: default-app
X-Sun-Data-Description: default
X-Sun-Data-Name: numeric_limits.pl
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 267
#!/usr/bin/perl -w
head();
@int_types = ("char", "short char", "unsigned char", "short int",
"unsigned short int", "int", "unsigned int", "long int",
"unsigned long int", "long long int", "unsigned long long int");
foreach $int_type (@int_types)
{
int_type_specialization($int_type);
}
@float_types = ("float","double","long double");
foreach $float_type (@float_types)
{
float_type_specialization($float_type);
}
bottom();
### -----------------------------------------
sub head
{
print <<'END_HEAD';
#ifndef _LIMITS_
#define _LIMITS_
#include <cfloat>
#include <climit>
extern "C++"
{
enum float_round_style {
round_indeterminate = -1,
round_toward_zero = 0,
round_to_nearest = 1,
round_toward_infinity = 2,
round_toward_beg_infinity = 3
};
template<class T> class numeric_limits
{
public:
static const bool is_specialized = false;
// radix of exponent representation
static const int radix = 0;
// number of radix digit in mantissa
static const int digits = 0;
// number of base 10 digits in mantissa
static const int digit10 = 0;
static const bool is_signed = false;
static const bool is_integer = false;
static const bool is_exact = false;
// minimum normalized value
static T min( ) throw( );
// maximum value
static T max( ) throw( );
// difference between T(1.0) and the minimum
// value of type T greater than T(1.0)
static T epsilon( ) throw( );
// minimum int x such that radix**(x-1) is a normalised T value
static const int min_exponent = 0;
// minimum int x such that 10**x is a representable T value
static const int min_exponent10 = 0;
// maximum int x such that radix**(x-1) is a normalised T value
static const int max_exponent = 0;
// maximum int x such that 10**x is a representable T value
static const int max_exponent10 = 0;
static const bool has_infinity = false;
static const bool has_quiet_NaN = false;
static const bool has_signaling_NaN = false;
static const bool has_denorm = false;
static const bool has_denorm_loss = false;
static T infinity( ) throw( );
static T quiet_NaN( ) throw( );
static T signaling_NaN( ) throw( );
static T denorm_min( ) throw( );
static const bool is_iec559 = false;
static const bool is_bounded = false;
static const bool is_modulo = false;
static const bool traps = false;
static const bool tinyness_before = false;
static const float_round_style round_style = round_toward_zero;
};
END_HEAD
} # sub head
### -----------------------------------------
sub bottom
{
print <<'END_BOTTOM';
} // extern "C++"
// Local Variables:
// mode:C++
// End:
END_BOTTOM
} # sub bottom
### -----------------------------------------
sub float_type_specialization
{
my %rep = (
"float" => "FLT",
"double" => "DBL",
"long double" => "LDBL"
);
my $type = shift;
# provide the specialization
print <<"END_FLOAT_SPECIALIZATION";
template<> class numeric_limits<$type>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = FLT_RADIX;
// number of radix digit in mantissa
static const int digits = $rep{$type}_MANT_DIG;
// number of base 10 digits in mantissa
static const int digit10 = $rep{$type}_DIG;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
// minimum normalized \'$type\'
static $type min( ) throw( ) { return $rep{$type}_MIN; }
// maximum \'$type\'
static $type max( ) throw( ) { return $rep{$type}_MAX; }
// difference between ($type)(1.0) and the minimum
// \'$type\' greater than ($type)(1.0)
static $type epsilon( ) throw( ) { return $rep{$type}_EPSILON; }
// minimum int x such that radix**(x-1) is a normalised \'$type\'
static const int min_exponent = $rep{$type}_MIN_EXP;
// minimum int x such that 10**x is a representable \'$type\'
static const int min_exponent10 = $rep{$type}_MIN_10_EXP;
// maximum int x such that radix**(x-1) is a normalised \'$type\'
static const int max_exponent = $rep{$type}_MAX_EXP;
// maximum int x such that 10**x is a representable \'$type\'
static const int max_exponent10 = $rep{$type}_MAX_10_EXP;
static const float_round_style round_style = float_round_style(FLT_ROUNDS);
};
END_FLOAT_SPECIALIZATION
} #sub float_type_specialization
### -----------------------------------------
sub int_type_specialization
{
my %rep = (
"char" => "CHAR",
"short char" => "SCHAR",
"unsigned char" => "UCHAR",
"short int" => "SHRT",
"unsigned short int" => "USHRT",
"int" => "INT",
"unsigned int" => "UINT",
"long int" => "LONG",
"unsigned long int" => "ULONG",
"long long int" => "LONG_LONG",
"unsigned long long int" => "ULONG_LONG"
);
my $type = shift;
my $signed = "true";
if ( $type =~ /unsigned/ )
{
$signed = "false";
}
# provide the specialization
print <<"END_INT_SPECIALIZATION";
template<> class numeric_limits<$type>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = $signed;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a \'$type\' can hold
static $type min( ) throw( ) { return $rep{$type}_MIN; }
// maximum value a \'$type\' can hold
static $type max( ) throw( ) { return $rep{$type}_MAX; }
};
END_INT_SPECIALIZATION
} #sub int_type_specialization
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: limits
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 529
#ifndef _LIMITS_
#define _LIMITS_
#include <cfloat>
#include <climit>
extern "C++"
{
enum float_round_style {
round_indeterminate = -1,
round_toward_zero = 0,
round_to_nearest = 1,
round_toward_infinity = 2,
round_toward_beg_infinity = 3
};
template<class T> class numeric_limits
{
public:
static const bool is_specialized = false;
// radix of exponent representation
static const int radix = 0;
// number of radix digit in mantissa
static const int digits = 0;
// number of base 10 digits in mantissa
static const int digit10 = 0;
static const bool is_signed = false;
static const bool is_integer = false;
static const bool is_exact = false;
// minimum normalized value
static T min( ) throw( );
// maximum value
static T max( ) throw( );
// difference between T(1.0) and the minimum
// value of type T greater than T(1.0)
static T epsilon( ) throw( );
// minimum int x such that radix**(x-1) is a normalised T value
static const int min_exponent = 0;
// minimum int x such that 10**x is a representable T value
static const int min_exponent10 = 0;
// maximum int x such that radix**(x-1) is a normalised T value
static const int max_exponent = 0;
// maximum int x such that 10**x is a representable T value
static const int max_exponent10 = 0;
static const bool has_infinity = false;
static const bool has_quiet_NaN = false;
static const bool has_signaling_NaN = false;
static const bool has_denorm = false;
static const bool has_denorm_loss = false;
static T infinity( ) throw( );
static T quiet_NaN( ) throw( );
static T signaling_NaN( ) throw( );
static T denorm_min( ) throw( );
static const bool is_iec559 = false;
static const bool is_bounded = false;
static const bool is_modulo = false;
static const bool traps = false;
static const bool tinyness_before = false;
static const float_round_style round_style = round_toward_zero;
};
template<> class numeric_limits<char>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = true;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'char' can hold
static char min( ) throw( ) { return CHAR_MIN; }
// maximum value a 'char' can hold
static char max( ) throw( ) { return CHAR_MAX; }
};
template<> class numeric_limits<short char>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = true;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'short char' can hold
static short char min( ) throw( ) { return SCHAR_MIN; }
// maximum value a 'short char' can hold
static short char max( ) throw( ) { return SCHAR_MAX; }
};
template<> class numeric_limits<unsigned char>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = false;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'unsigned char' can hold
static unsigned char min( ) throw( ) { return UCHAR_MIN; }
// maximum value a 'unsigned char' can hold
static unsigned char max( ) throw( ) { return UCHAR_MAX; }
};
template<> class numeric_limits<short int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = true;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'short int' can hold
static short int min( ) throw( ) { return SHRT_MIN; }
// maximum value a 'short int' can hold
static short int max( ) throw( ) { return SHRT_MAX; }
};
template<> class numeric_limits<unsigned short int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = false;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'unsigned short int' can hold
static unsigned short int min( ) throw( ) { return USHRT_MIN; }
// maximum value a 'unsigned short int' can hold
static unsigned short int max( ) throw( ) { return USHRT_MAX; }
};
template<> class numeric_limits<int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = true;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'int' can hold
static int min( ) throw( ) { return INT_MIN; }
// maximum value a 'int' can hold
static int max( ) throw( ) { return INT_MAX; }
};
template<> class numeric_limits<unsigned int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = false;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'unsigned int' can hold
static unsigned int min( ) throw( ) { return UINT_MIN; }
// maximum value a 'unsigned int' can hold
static unsigned int max( ) throw( ) { return UINT_MAX; }
};
template<> class numeric_limits<long int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = true;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'long int' can hold
static long int min( ) throw( ) { return LONG_MIN; }
// maximum value a 'long int' can hold
static long int max( ) throw( ) { return LONG_MAX; }
};
template<> class numeric_limits<unsigned long int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = false;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'unsigned long int' can hold
static unsigned long int min( ) throw( ) { return ULONG_MIN; }
// maximum value a 'unsigned long int' can hold
static unsigned long int max( ) throw( ) { return ULONG_MAX; }
};
template<> class numeric_limits<long long int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = true;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'long long int' can hold
static long long int min( ) throw( ) { return LONG_LONG_MIN; }
// maximum value a 'long long int' can hold
static long long int max( ) throw( ) { return LONG_LONG_MAX; }
};
template<> class numeric_limits<unsigned long long int>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = 2;
static const bool is_signed = false;
static const bool is_integer = true;
static const bool is_exact = true;
// minimum value a 'unsigned long long int' can hold
static unsigned long long int min( ) throw( ) { return ULONG_LONG_MIN; }
// maximum value a 'unsigned long long int' can hold
static unsigned long long int max( ) throw( ) { return ULONG_LONG_MAX; }
};
template<> class numeric_limits<float>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = FLT_RADIX;
// number of radix digit in mantissa
static const int digits = FLT_MANT_DIG;
// number of base 10 digits in mantissa
static const int digit10 = FLT_DIG;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
// minimum normalized 'float'
static float min( ) throw( ) { return FLT_MIN; }
// maximum 'float'
static float max( ) throw( ) { return FLT_MAX; }
// difference between (float)(1.0) and the minimum
// 'float' greater than (float)(1.0)
static float epsilon( ) throw( ) { return FLT_EPSILON; }
// minimum int x such that radix**(x-1) is a normalised 'float'
static const int min_exponent = FLT_MIN_EXP;
// minimum int x such that 10**x is a representable 'float'
static const int min_exponent10 = FLT_MIN_10_EXP;
// maximum int x such that radix**(x-1) is a normalised 'float'
static const int max_exponent = FLT_MAX_EXP;
// maximum int x such that 10**x is a representable 'float'
static const int max_exponent10 = FLT_MAX_10_EXP;
static const float_round_style round_style = float_round_style(FLT_ROUNDS);
};
template<> class numeric_limits<double>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = FLT_RADIX;
// number of radix digit in mantissa
static const int digits = DBL_MANT_DIG;
// number of base 10 digits in mantissa
static const int digit10 = DBL_DIG;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
// minimum normalized 'double'
static double min( ) throw( ) { return DBL_MIN; }
// maximum 'double'
static double max( ) throw( ) { return DBL_MAX; }
// difference between (double)(1.0) and the minimum
// 'double' greater than (double)(1.0)
static double epsilon( ) throw( ) { return DBL_EPSILON; }
// minimum int x such that radix**(x-1) is a normalised 'double'
static const int min_exponent = DBL_MIN_EXP;
// minimum int x such that 10**x is a representable 'double'
static const int min_exponent10 = DBL_MIN_10_EXP;
// maximum int x such that radix**(x-1) is a normalised 'double'
static const int max_exponent = DBL_MAX_EXP;
// maximum int x such that 10**x is a representable 'double'
static const int max_exponent10 = DBL_MAX_10_EXP;
static const float_round_style round_style = float_round_style(FLT_ROUNDS);
};
template<> class numeric_limits<long double>
{
public:
static const bool is_specialized = true;
// radix of exponent representation
static const int radix = FLT_RADIX;
// number of radix digit in mantissa
static const int digits = LDBL_MANT_DIG;
// number of base 10 digits in mantissa
static const int digit10 = LDBL_DIG;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
// minimum normalized 'long double'
static long double min( ) throw( ) { return LDBL_MIN; }
// maximum 'long double'
static long double max( ) throw( ) { return LDBL_MAX; }
// difference between (long double)(1.0) and the minimum
// 'long double' greater than (long double)(1.0)
static long double epsilon( ) throw( ) { return LDBL_EPSILON; }
// minimum int x such that radix**(x-1) is a normalised 'long double'
static const int min_exponent = LDBL_MIN_EXP;
// minimum int x such that 10**x is a representable 'long double'
static const int min_exponent10 = LDBL_MIN_10_EXP;
// maximum int x such that radix**(x-1) is a normalised 'long double'
static const int max_exponent = LDBL_MAX_EXP;
// maximum int x such that 10**x is a representable 'long double'
static const int max_exponent10 = LDBL_MAX_10_EXP;
static const float_round_style round_style = float_round_style(FLT_ROUNDS);
};
} // extern "C++"
// Local Variables:
// mode:C++
// End: