I'm writing a template, and I need to know the maximum value of a given
integer type at compile time. something like:
template<class NumType>
class Arb {
public:
static NumType const max = /* maximum value */;
};
If the template were only to be used with unsigned integer types, then
I'd do the following:
template<class NumType>
class Arb {
public:
static NumType const max = 1;
};
I need a compiletime constant which evaluates to the maximum value of an
integer type.
Any ideas?
If it weren't undefined behaviour to overflow a signed integer, I could
use a metaprogramming technique such as the following:
template<class T, bool overflow = false>
struct MaxIntVal {
private:
static T const internal = 1 + MaxIntVal<T,...
public:
static T const val = SCHAR_MAX + internal;
};

Frederick Gotham 35 12499
* Frederick Gotham:
I'm writing a template, and I need to know the maximum value of a given
integer type at compile time.
template< typename T struct Max;
template<struct Max<int>{ static int const value = INT_MAX; };
and so on

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
Frederick Gotham wrote:
>
I need a compiletime constant which evaluates to the maximum value of an
integer type.
Are you sure it has to be compile time? If not just use
std::numeric_limits<T>::max()

Ian Collins.
I have a solution (although I intend on making it more compiletime
efficient as I can assume that "digits" is at least 7).
#include<limits>
template< class T,
T shift_by = 0,
bool no_more_digits = shift_by == std::numeric_limits
<T>::digits
>
struct IntMax {
private:
static T const one = 1;
public:
static T const val = (one << shift_by)  IntMax<T,shift_by +
one>::val;
};
template<class T, T shift_by>
struct IntMax<T,shift_by,true{
static T const val = 0;
};
#include <iostream>
int main()
{
std::cout <<
"Max values\n"
"============\n\n"
" Signed char: " << (int)IntMax<signed char>::val <<
"\nSigned short: " << IntMax<short>::val <<
"\n Signed int: " << IntMax<int>::val <<
"\n Signed long: " << IntMax<long>::val;
}

Frederick Gotham
Frederick Gotham posted:
>
I have a solution (although I intend on making it more compiletime
efficient as I can assume that "digits" is at least 7).
Here's the more efficient version:
#include<limits>
template< class T,
T shift_by,
bool no_more_digits = shift_by == std::numeric_limits
<T>::digits
>
struct IntMax_Internal {
private:
static T const one = 1;
public:
static T const val = (one << shift_by)  IntMax_Internal<T,shift_by +
one>::val;
};
template<class T, T shift_by>
struct IntMax_Internal<T,shift_by,true{
static T const val = 0;
};
template< class T >
struct IntMax {
private:
static T const one_two_seven = 127;
public:
static T const val = one_two_seven  IntMax_Internal<T,7>::val;
};
#include <iostream>
int main()
{
std::cout <<
"Max values\n"
"==========\n\n"
" Unsigned char: " << (int)IntMax<unsigned char>::val <<
"\nUnsigned short: " << IntMax<unsigned short>::val <<
"\n Unsigned int: " << IntMax<unsigned>::val <<
"\n Unsigned long: " << IntMax<unsigned long>::val <<
"\n\n Signed char: " << (int)IntMax<signed char>::val <<
"\n Signed short: " << IntMax<short>::val <<
"\n Signed int: " << IntMax<int>::val <<
"\n Signed long: " << IntMax<long>::val;
}

Frederick Gotham
Frederick Gotham wrote:
template< class T,
T shift_by,
bool no_more_digits = shift_by == std::numeric_limits
<T>::digits
>
....
Although this would probably work 99% of the time, I think technically
that the standard does not require 2s compliment arithmetic (or
whatever it is called)  ie you can't assume setting all bits to 1
gives you the largest value.
As mentioned earlier, I think you would be better using INT_MAX, etc in
a bunch of specializations.
If you wanted to get really perverse, you might be able to do something
somehow similar to using bits  recursively double the value until it
doesn't get bigger, then (restore last largest value and) start adding
half as much, then 1/4, etc until you are not adding anything.
eg if max is 20 (strange max!)
search = 1;
try adding 2? =search = 3;
+ 4 ? =search = 7;
+ 8 ? =search = 15;
+ 16 ? =overflow!!  back off!
+ 8 ? =overflow!!
+ 4 ? =search = 19
+ 2 ? =overflow!
+ 1 ? =search = 20.
stop because you are at 1. If there was 'room' to add another 1, then
+ 2 would have worked.
Anyhow, perserve, and not really understandable by the next coder who
looks at it  even if that is you 2 years from now. But I suspect it
could be coded with templates.
Of course, I don't know what the standard says will happen when compile
time constants 'overflow'....
 Tony
Frederick Gotham wrote:
I have a solution (although I intend on making it more compiletime
efficient as I can assume that "digits" is at least 7).
#include<limits>
template< class T,
T shift_by = 0,
bool no_more_digits = shift_by == std::numeric_limits
<T>::digits
>
struct IntMax {
private:
static T const one = 1;
public:
static T const val = (one << shift_by)  IntMax<T,shift_by +
one>::val;
};
template<class T, T shift_by>
struct IntMax<T,shift_by,true{
static T const val = 0;
};
If you can use numeric_limits::digits, wouldn't this be simpler?
template <typename T>
struct intinfo {
static const T max = (static_cast<T>(1) <<
std::numeric_limits<T>::digits  1)  1 << 1  1;
};
Or are there some special cases this doesn't handle correctly?
Ian Collins wrote:
Frederick Gotham wrote:
>> I need a compiletime constant which evaluates to the maximum value of an integer type.
Are you sure it has to be compile time? If not just use
std::numeric_limits<T>::max()
I guess there must be a good reason why this is not a compiletime constant,
but a function. I don't think that there could be an implementation where
those values change during runtime, so what is the reason to make it a
function?
posted:
>
Frederick Gotham wrote:
>template< class T, T shift_by, bool no_more_digits = shift_by == std::numeric_limits <T>::digits
> >
...
Although this would probably work 99% of the time, I think technically
that the standard does not require 2s compliment arithmetic (or
whatever it is called)  ie you can't assume setting all bits to 1
gives you the largest value.
"digits" gives you the amount of value bits, excluding the sign bit.
If the sign bit (if any) is zero, and if all the rest of the bits are 1,
then you have the max value.

Frederick Gotham
=?utf8?B?SGFyYWxkIHZhbiBExLNr?= posted:
If you can use numeric_limits::digits, wouldn't this be simpler?
template <typename T>
struct intinfo {
static const T max = (static_cast<T>(1) <<
std::numeric_limits<T>::digits  1)  1 << 1  1;
};
Or are there some special cases this doesn't handle correctly?
That's brilliant. Here's the updated code:
#include<limits>
template<class T>
struct IntMax {
private:
static T const MSBOnly = static_cast<T>(1) << std::numeric_limits
<T>::digits  1;
public:
static T const val = MSBOnly  MSBOnly  1;
};
#include <iostream>
int main()
{
std::cout <<
"Max values\n"
"==========\n\n"
" Unsigned char: " << (int)IntMax<unsigned char>::val <<
"\nUnsigned short: " << IntMax<unsigned short>::val <<
"\n Unsigned int: " << IntMax<unsigned>::val <<
"\n Unsigned long: " << IntMax<unsigned long>::val <<
"\n\n Signed char: " << (int)IntMax<signed char>::val <<
"\n Signed short: " << IntMax<short>::val <<
"\n Signed int: " << IntMax<int>::val <<
"\n Signed long: " << IntMax<long>::val;
}

Frederick Gotham
"Frederick Gotham" <fg*******@SPAM.comskrev i meddelandet
news:F9*******************@news.indigo.ie...
posted:
>> Frederick Gotham wrote:
>>template< class T, T shift_by, bool no_more_digits = shift_by == std::numeric_limits <T>::digits >
...
Although this would probably work 99% of the time, I think technically that the standard does not require 2s compliment arithmetic (or whatever it is called)  ie you can't assume setting all bits to 1 gives you the largest value.
"digits" gives you the amount of value bits, excluding the sign bit.
If the sign bit (if any) is zero, and if all the rest of the bits
are 1,
then you have the max value.
This of course assumes that all the bits take part in the value
representation. Not a requirement.
You are now at 99.5% mark, I guess. :)
There is a reason for the seemingly redundant values in
numeric_limits  implementations are allowed to have unusual values
for some of them.
Bo Persson
Bo Persson posted:
This of course assumes that all the bits take part in the value
representation. Not a requirement.
18.2.1.2 numeric_limits members
static const int digits;
6 Number of radix digits that can be represented without change.
7 For builtin integer types, the number of nonsign bits in the
representation.

Frederick Gotham
Bo Persson wrote:
>"digits" gives you the amount of value bits, excluding the sign bit.
If the sign bit (if any) is zero, and if all the rest of the bits are 1, then you have the max value.
This of course assumes that all the bits take part in the value
representation.
AFAICS, it doesn't. As Frederick wrote, "digits" gives you the amount of
_value bits_, not the total amount of bits.
* Frederick Gotham:
=?utf8?B?SGFyYWxkIHZhbiBExLNr?= posted:
>If you can use numeric_limits::digits, wouldn't this be simpler?
template <typename T> struct intinfo { static const T max = (static_cast<T>(1) << std::numeric_limits<T>::digits  1)  1 << 1  1; };
Or are there some special cases this doesn't handle correctly?
That's brilliant. Here's the updated code:
#include<limits>
template<class T>
struct IntMax {
private:
static T const MSBOnly = static_cast<T>(1) << std::numeric_limits
<T>::digits  1;
public:
static T const val = MSBOnly  MSBOnly  1;
};
It's good fun to throw academic spanners into practical wheels, so,
where does the standard exclude a greycode representation? ;)

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
Alf P. Steinbach posted:
It's good fun to throw academic spanners into practical wheels, so,
where does the standard exclude a greycode representation? ;)
Only caveat that comes to mind is negative zero... but that shouldn't be an
issue here.
Unless you're talking about leftshifting a signed integer type... ?
(Not quite sure what you mean by "exclude a greycode representation")

Frederick Gotham
* Frederick Gotham:
Alf P. Steinbach posted:
>It's good fun to throw academic spanners into practical wheels, so, where does the standard exclude a greycode representation? ;)
Only caveat that comes to mind is negative zero... but that shouldn't be an
issue here.
Unless you're talking about leftshifting a signed integer type... ?
(Not quite sure what you mean by "exclude a greycode representation")
Frederick, I give you also (as I gave Protoman)... WIKIPEDIA!
<url: http://en.wikipedia.org/wiki/Grey_code>
Note the bit pattern for the highest value when using a given number of
bits.
Sorry for the typo.
Coming from a whaling country, I naturally prefer Earl Grey tea...

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
Alf P. Steinbach posted:
Note the bit pattern for the highest value when using a given number of
bits.
I was under the assumption that C++ had to store positive values as
follows:
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
8: 1000
9: 1001
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
Are you saying that:
(A) The machine could use another method such as "Gray code".
and
(B) My code could break on other systems, and thus isn't trully
portable?

Frederick Gotham
Alf P. Steinbach wrote:
It's good fun to throw academic spanners into practical wheels, so,
where does the standard exclude a greycode representation? ;)
Hmm, I would have said 3.9.1/7, but after reading it again, it seems that
this actually doesn't prohibit a greycode representation.
Rolf Magnus wrote:
Alf P. Steinbach wrote:
>It's good fun to throw academic spanners into practical wheels, so, where does the standard exclude a greycode representation? ;)
Hmm, I would have said 3.9.1/7, but after reading it again, it seems that
this actually doesn't prohibit a greycode representation.
Ok, now I have one: 5.8/2.
Rolf Magnus posted:
Ok, now I have one: 5.8/2.
The value of E1 << E2 is E1 (interpreted as a bit pattern) leftshifted E2
bit positions; vacated bits are zerofilled. If E1 has an unsigned type,
the value of the result is E1 multiplied by the quantity 2 raised to the
power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long,
UINT_MAX+1 otherwise.
Is it the "vacated bits are zerofilled" part that you're talking about?

Frederick Gotham
* Frederick Gotham:
Alf P. Steinbach posted:
>Note the bit pattern for the highest value when using a given number of bits.
I was under the assumption that C++ had to store positive values as
follows:
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
8: 1000
9: 1001
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
Are you saying that:
(A) The machine could use another method such as "Gray code".
and
(B) My code could break on other systems, and thus isn't trully
portable?
It's just academic, but yes. §5.8/2 defines the result of << as a
bitlevel operation, and as a value only for unsigned types. §5.8/3
defines the result of >as a bitlevel operation and as a value both
for signed and unsigned types (the latter only for nonnegative values).
The cases excluded from these definitions are, AFAICT, exactly those
where the definitions would otherwise be incompatible with greycode...

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
* Rolf Magnus:
Rolf Magnus wrote:
>Alf P. Steinbach wrote:
>>It's good fun to throw academic spanners into practical wheels, so, where does the standard exclude a greycode representation? ;)
Hmm, I would have said 3.9.1/7, but after reading it again, it seems that this actually doesn't prohibit a greycode representation.
Ok, now I have one: 5.8/2.
Nope, not as far as I can see: it's /very/ ingeniously worded so that
the cases that could be incompatible are simply not defined.

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
* Alf P. Steinbach:
greycode
Sorry, again: _gray code_.

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
Frederick Gotham wrote:
Rolf Magnus posted:
>Ok, now I have one: 5.8/2.
The value of E1 << E2 is E1 (interpreted as a bit pattern) leftshifted E2
bit positions; vacated bits are zerofilled. If E1 has an unsigned type,
the value of the result is E1 multiplied by the quantity 2 raised to the
power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long,
UINT_MAX+1 otherwise.
Is it the "vacated bits are zerofilled" part that you're talking about?
No, it's the "(interpreted as a bit pattern) leftshifted E2 bit positions"
in combination with the "multiplied by the quantity 2 raised to the power
E2". If your values are represented in gray code, a leftshift of the bit
pattern doesn't necessarily result in a mulitplication by 2.
* Rolf Magnus:
Frederick Gotham wrote:
>Rolf Magnus posted:
>>Ok, now I have one: 5.8/2.
The value of E1 << E2 is E1 (interpreted as a bit pattern) leftshifted E2 bit positions; vacated bits are zerofilled. If E1 has an unsigned type, the value of the result is E1 multiplied by the quantity 2 raised to the power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 otherwise.
Is it the "vacated bits are zerofilled" part that you're talking about?
No, it's the "(interpreted as a bit pattern) leftshifted E2 bit positions"
in combination with the "multiplied by the quantity 2 raised to the power
E2". If your values are represented in gray code, a leftshift of the bit
pattern doesn't necessarily result in a mulitplication by 2.
That's only for unsigned types. C++ unsigned integers are pure binary.
For signed integers there's much more leeway (formally).

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
Alf P. Steinbach wrote:
* Rolf Magnus:
>Rolf Magnus wrote:
>>Alf P. Steinbach wrote:
It's good fun to throw academic spanners into practical wheels, so, where does the standard exclude a greycode representation? ;) Hmm, I would have said 3.9.1/7, but after reading it again, it seems that this actually doesn't prohibit a greycode representation.
Ok, now I have one: 5.8/2.
Nope, not as far as I can see: it's /very/ ingeniously worded so that
the cases that could be incompatible are simply not defined.
What's not defined? It says clearly that the bit pattern is shifted left by
the specified number of bits and that this will (for unsigned types) result
in a multiplication by 2 raised to the value of the rhs. That's not
possible with Gray code, so unsigned types cannot use Gray code. Since a
bit pattern for a signed value must be the same as for the corresponding
unsigned value, signed types neither can use Gray code.
Alf P. Steinbach wrote:
* Rolf Magnus:
>Frederick Gotham wrote:
>>Rolf Magnus posted:
Ok, now I have one: 5.8/2. The value of E1 << E2 is E1 (interpreted as a bit pattern) leftshifted E2 bit positions; vacated bits are zerofilled. If E1 has an unsigned type, the value of the result is E1 multiplied by the quantity 2 raised to the power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 otherwise.
Is it the "vacated bits are zerofilled" part that you're talking about?
No, it's the "(interpreted as a bit pattern) leftshifted E2 bit positions" in combination with the "multiplied by the quantity 2 raised to the power E2". If your values are represented in gray code, a leftshift of the bit pattern doesn't necessarily result in a mulitplication by 2.
That's only for unsigned types. C++ unsigned integers are pure binary.
For signed integers there's much more leeway (formally).
Only for the negative values. So I guess a signed integer could use Gray
code for the negative part. That would be extremely odd, but seems to be
allowed by the standard.
* Rolf Magnus:
Alf P. Steinbach wrote:
>* Rolf Magnus:
>>Frederick Gotham wrote:
Rolf Magnus posted:
Ok, now I have one: 5.8/2. The value of E1 << E2 is E1 (interpreted as a bit pattern) leftshifted E2 bit positions; vacated bits are zerofilled. If E1 has an unsigned type, the value of the result is E1 multiplied by the quantity 2 raised to the power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 otherwise.
Is it the "vacated bits are zerofilled" part that you're talking about? No, it's the "(interpreted as a bit pattern) leftshifted E2 bit positions" in combination with the "multiplied by the quantity 2 raised to the power E2". If your values are represented in gray code, a leftshift of the bit pattern doesn't necessarily result in a mulitplication by 2.
That's only for unsigned types. C++ unsigned integers are pure binary. For signed integers there's much more leeway (formally).
Only for the negative values. So I guess a signed integer could use Gray
code for the negative part. That would be extremely odd, but seems to be
allowed by the standard.
No, it's for any (signed) value. Left shift doesn't define the numeric
value. And right shift >does define the value but is all OK.

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
* Rolf Magnus:
Alf P. Steinbach wrote:
>* Rolf Magnus:
>>Rolf Magnus wrote:
Alf P. Steinbach wrote:
It's good fun to throw academic spanners into practical wheels, so, where does the standard exclude a greycode representation? ;) Hmm, I would have said 3.9.1/7, but after reading it again, it seems that this actually doesn't prohibit a greycode representation. Ok, now I have one: 5.8/2.
Nope, not as far as I can see: it's /very/ ingeniously worded so that the cases that could be incompatible are simply not defined.
What's not defined? It says clearly that the bit pattern is shifted left by
the specified number of bits and that this will (for unsigned types) result
in a multiplication by 2 raised to the value of the rhs. That's not
possible with Gray code, so unsigned types cannot use Gray code. Since a
bit pattern for a signed value must be the same as for the corresponding
unsigned value, signed types neither can use Gray code.
No, the bit pattern for a signed value must not necessarily be the same
as for the corresponding unsigned value. In particular, that very
obviously doesn't hold for negative values. And by extension, it
doesn't hold for nonnegative values either (if you're looking at the
same paragraph which has been discussed to death in this connection
before [the solution, if it may be called that, is then to look at the
definitions of terms] ;)).

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
Alf P. Steinbach wrote:
* Rolf Magnus:
>Alf P. Steinbach wrote:
>>* Rolf Magnus: Rolf Magnus wrote:
Alf P. Steinbach wrote: > >It's good fun to throw academic spanners into practical wheels, so, >where does the standard exclude a greycode representation? ;) Hmm, I would have said 3.9.1/7, but after reading it again, it seems that this actually doesn't prohibit a greycode representation. Ok, now I have one: 5.8/2. Nope, not as far as I can see: it's /very/ ingeniously worded so that the cases that could be incompatible are simply not defined.
What's not defined? It says clearly that the bit pattern is shifted left by the specified number of bits and that this will (for unsigned types) result in a multiplication by 2 raised to the value of the rhs. That's not possible with Gray code, so unsigned types cannot use Gray code. Since a bit pattern for a signed value must be the same as for the corresponding unsigned value, signed types neither can use Gray code.
No, the bit pattern for a signed value must not necessarily be the same
as for the corresponding unsigned value. In particular, that very
obviously doesn't hold for negative values. And by extension, it
doesn't hold for nonnegative values either (if you're looking at the
same paragraph which has been discussed to death in this connection
before [the solution, if it may be called that, is then to look at the
definitions of terms] ;)).
You must be talking about :
"The range of nonnegative values of a signed integer type is a subrange of
the corresponding unsigned integer type, and the value representation of
each corresponding signed/unsigned type shall be the same."
Not sure what's wrong about that, though. Doesn't it mean that the same
value in a corresponding signed and unsigned type must have the same bit
pattern? Obviously, that's only possible for the subrange that is covered
by both.
* Rolf Magnus Alf P. Steinbach:
>
You must be talking about:
"The range of nonnegative values of a signed integer type is a subrange of
the corresponding unsigned integer type, and the value representation of
each corresponding signed/unsigned type shall be the same."
Yep.
Not sure what's wrong about that, though. Doesn't it mean that the same
value in a corresponding signed and unsigned type must have the same bit
pattern?
Nope, partly because:
Obviously, that's only possible for the subrange that is covered
by both.
and partly because of earlier definition of "value representation".

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email?
"Rolf Magnus" <ra******@tonline.deskrev i meddelandet
news:e8*************@news.tonline.com...
Bo Persson wrote:
>>"digits" gives you the amount of value bits, excluding the sign bit.
If the sign bit (if any) is zero, and if all the rest of the bits are 1, then you have the max value.
This of course assumes that all the bits take part in the value representation.
AFAICS, it doesn't. As Frederick wrote, "digits" gives you the
amount of
_value bits_, not the total amount of bits.
Does too! :)
How do we know exactly what bits of the object takes part in the value
representation? Is the sign bit always the first bit? Where are the
pad bits?
If we always assume 32 bits, two's complement, and no pad bits, we can
skip all this. If we want to be totally portable, we cannot assume any
of it.
Part of the reason for me being so picky, is that on my CS courses we
used a Univac 1100  36 bit, one's complement. Compatible machines
still exist!
Bo Persson
Bo Persson posted:
Does too! :)
How do we know exactly what bits of the object takes part in the value
representation? Is the sign bit always the first bit? Where are the
pad bits?
That's the compiler's job to worry about. We just give it the value of the
bit we want, rather than the bit index, and it works out the rest.
Furthermore, the Standard guarantees that:
x << 1
is equal to:
x * 2

Frederick Gotham
Alf P. Steinbach wrote:
the bit pattern for a signed value must not necessarily be the same
as for the corresponding unsigned value. In particular, that very
obviously doesn't hold for negative values. And by extension, it
doesn't hold for nonnegative values either
I don't agree with your extension. Take a simple 16 bit int. The
common value subrange is [0,32767], for which bits 015 are defined
by the unsigned int representation. For this range, and this range
only,
the representation of int and unsigned int must match. The fact that
the ranges [32768,1] for int and [32768,65536] for unsigned are not
common means the bit patterns for these ranges may overlap
(must, if only 16 bits are available) but that only says something
about
bit patterns where bit 15 is set.
I have a better solution.
The highest value is equal to:
(radix ^ digits)  1
(I thought it might work for floating point types aswell, but it
doesn't.)
First I start off with a metaprogramming template to raise a number to a
positive integer power, and work from there:
#include <limits>
template<class T, unsigned long base, unsigned long exp,
bool exp_non_zero = !!exp>
struct IntPow {
static T const val = base * IntPow<T,base,exp1>::val;
};
template<class T, unsigned long base, unsigned long exp>
struct IntPow<T,base,exp,false{
static T const val = 1;
};
template<class T>
struct IntMax {
typedef std::numeric_limits<TLim;
static T const val =
IntPow<T, Lim::radix, Lim::digits>::val  1;
};
#include <iostream>
int main()
{
std::cout <<
"Max values\n"
"==========\n\n"
" unsigned char: " << (int)IntMax<unsigned char>::val <<
"\nunsigned short: " << IntMax<unsigned short>::val <<
"\n unsigned int: " << IntMax<unsigned>::val <<
"\n unsigned long: " << IntMax<unsigned long>::val <<
"\n\n signed char: " << (int)IntMax<signed char>::val <<
"\n signed short: " << IntMax<short>::val <<
"\n signed int: " << IntMax<int>::val <<
"\n signed long: " << IntMax<long>::val;
/*
std::cout <<
"\n float: " << IntMax<float>::val <<
"\n double: " << IntMax<float>::val <<
"\n long double: " << IntMax<float>::val;
*/
}

Frederick Gotham
* Mi*************@tomtom.com:
Alf P. Steinbach wrote:
the bit pattern for a signed value must not necessarily be the same
>as for the corresponding unsigned value. In particular, that very obviously doesn't hold for negative values. And by extension, it doesn't hold for nonnegative values either
I don't agree with your extension. Take a simple 16 bit int. The
common value subrange is [0,32767], for which bits 015 are defined
by the unsigned int representation. For this range, and this range
only,
the representation of int and unsigned int must match.
What is the argument?

A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Topposting.
Q: What is the most annoying thing on usenet and in email? This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Glenn Venzke 
last post by:
I'm writing a class with a method that will accept 1 of 3 items listed in an
enum. Is it possible to pass the item name without the enum name in your
calling statement?
EXAMPLE:
public enum...

by: Semi Head 
last post by:
Hello folks, I'm looking for a script to validate a specific number
value in a standard form input field.
An example would be, if someone enters a number into a form input, I
want the script to...

by: Francois Grieu 
last post by:
The values of ((int)0.7) and ((int)0.7) seem to be 0
Is this independent of implementation ?
TIA,
François Grieu

by: Chris Bower 
last post by:
Reposted from aspnet.buildingcontrols:
Ok, I've got a bunch of derived controls that all have a property Rights of
type Rights (Rights is an Enumerator). I wrote a custom TypeConverter so
that I...

by: Jim in Arizona 
last post by:
I'm learning form an ASP.NET 1.0 book and I tried out some code that returns
this error:
Compiler Error Message: BC30311: Value of type 'Integer' cannot be converted
to...

by: Arne 
last post by:
Will the dataset below be returned by value or reference?
Public Shared Function getDS() As DataSet
Dim ds As New DataSet
'... do something
Return ds
End Function

by: MLH 
last post by:
120 MyString = "How many copies of each letter do you need?"
150 MyVariant = InputBox(MyString, "How Many?", "3")
If MyVariant = "2" Then MsgBox "MyVariant equals the string '2'"
If...

by: Tomás 
last post by:
Anything wrong with the following code?:
#include <cstdlib>
int main()
{
for (unsigned i = 0; i != 1000; ++i)
{
int *p = reinterpret_cast<int*>( std::rand() );

by: subramanian100in 
last post by:
Consider the following program
#include <limits.h>
#include <stddef.h>
int main(void)
{
size_t size;
size_t bytes = sizeof(size_t);

by: KK 
last post by:
Dear All
I have a small problem with using as operator on value type array.
Here is an example what I am trying to do.
using System;
using System.Collections.Generic;
using System.Text;

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: veera ravala 
last post by:
ServiceNow is a powerful cloudbased platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...

by: VivesProcSPL 
last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many Englishlike terms and syntax in an effort to make it easy to learn, particularly for...

by: isladogs 
last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
For other local times, please check World Time Buddy
In...

by: mar23 
last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...

by: abbasky 
last post by:
### Vandf component communication method one: data sharing
Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...

by: fareedcanada 
last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...

by: egorbl4 
last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это
Что это? Что мне с этим делать?
...

by: davi5007 
last post by:
Hi,
Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
 