Max value of an integer type?

  • Thread starter Frederick Gotham
  • Start date
A

Alf P. Steinbach

* Frederick Gotham:
Alf P. Steinbach posted:


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
bit-level operation, and as a value only for unsigned types. §5.8/3
defines the result of >> as a bit-level operation and as a value both
for signed and unsigned types (the latter only for non-negative values).
The cases excluded from these definitions are, AFAICT, exactly those
where the definitions would otherwise be incompatible with grey-code...
 
A

Alf P. Steinbach

* Rolf Magnus:
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.
 
R

Rolf Magnus

Frederick said:
Rolf Magnus posted:



The value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted E2
bit positions; vacated bits are zero-filled. 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 zero-filled" part that you're talking about?

No, it's the "(interpreted as a bit pattern) left-shifted 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 left-shift of the bit
pattern doesn't necessarily result in a mulitplication by 2.
 
A

Alf P. Steinbach

* Rolf Magnus:
No, it's the "(interpreted as a bit pattern) left-shifted 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 left-shift 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).
 
R

Rolf Magnus

Alf said:
* Rolf Magnus:

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.
 
R

Rolf Magnus

Alf said:
* Rolf Magnus:

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.
 
A

Alf P. Steinbach

* Rolf Magnus:
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

Alf P. Steinbach

* Rolf Magnus:
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 non-negative 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] ;-)).
 
R

Rolf Magnus

Alf said:
* Rolf Magnus:
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 non-negative 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.
 
A

Alf P. Steinbach

* 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".
 
B

Bo Persson

Rolf Magnus said:
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
 
F

Frederick Gotham

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
 
M

Michiel.Salters

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 non-negative 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 0-15 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.
 
F

Frederick Gotham

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,exp-1>::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<T> Lim;

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;
*/

}
 
A

Alf P. Steinbach

* (e-mail address removed):
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 non-negative 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 0-15 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?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,294
Latest member
LandonPigo

Latest Threads

Top