Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Type length in bits?

Reply
Thread Tools

Type length in bits?

 
 
Angel Tsankov
Guest
Posts: n/a
 
      04-24-2011

What is a standard way to get the "length in bits" (in the sense of
5.8/1) of a type?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 
Reply With Quote
 
 
 
 
Paul
Guest
Posts: n/a
 
      04-24-2011

"Angel Tsankov" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> What is a standard way to get the "length in bits" (in the sense of
> 5.8/1) of a type?
>
>

Hi,
I'm not sure if there is a standard way , but it depends on the length of
the orignal type.
If you have a long long and you left shift it, you won't get type promotion.
But you may have overflow or carry.
Here is one way to do it assuming the result fits into a promoted type.

int bits_per_byte = 8;
unsigned char uc = -1;
unsigned char shift_val = 1;

int num_bits = sizeof(uc)*bits_per_byte;
std::cout<< num_bits <<std::endl;
num_bits = sizeof(uc<< shift_val)*bits_per_byte;
std::cout<< num_bits;

If you change unsigned char uc , to an unsigned long type then this may not
work. I don't know if there is a way to get the number of bytes in that
case.
There is a way to get the value using floating point types , so therefore I
presume there is a way to do it. It an interested point worthy of more
thought IMO.

Note: There have been other suggestions to obtain a value for bits_per_byte
which may be more suitable in production code. I'm not sure if your question
was asking this simple point or the more complex point my answer has
addressed.





 
Reply With Quote
 
 
 
 
Matthias Hofmann
Guest
Posts: n/a
 
      04-29-2011

"Francis Glassborow" <(E-Mail Removed)> schrieb im
Newsbeitrag news:(E-Mail Removed)...
>
> I think there is a misunderstanding here. Fundamental types must use all
> the bits in their value representation but that is not the same as the
> amount of storage required. I.e. it is perfectly possible to have
> 64-bits of storage (8 octets) for an int but only use 32 bits for the
> value representation.


If a type would not use certain bits in its value representation, than these
bits wouldn't be part of the value representation, would they?

--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-01-2011
On Apr 30, 12:25 am, "Alf P. Steinbach /Usenet"
<(E-Mail Removed)> wrote:
> * Matthias Hofmann, on 29.04.2011 02:55:
> > "Alf P. Steinbach /Usenet"<(E-Mail Removed)> schrieb im
> > Newsbeitragnews:ip3phm$r9n$(E-Mail Removed)...

>
> >> C++98 3.9.1/1:


> >> "For character types, all bits of the object representation participate
> >> in the value representation. For unsigned character types, all possible
> >> bit patterns of the value representation represent numbers. These
> >> requirements do not hold for other types."


> >> And this language was unchanged in C++0x draft N3126, where it is the same
> >> paragraph number.


> > So if I understand this correctly, for types "char" and
> > "signed char", there may be bit patterns that do not
> > represent numbers, unless "char" is an unsigned type?


> Right.


Not for plain char. In C++. (This is, I think, a difference
between C and C++. C allows trapping bit patterns in plain
char. Not that it makes a difference in practice.)

[...]
> The standard mentions two's complement, one's complement and signed and
> magnitude as possible representations.


The C standard mentions these three formats, and says that the
value representation must be one of them. The current (03) C++
standard is a lot vaguer.

> Essentially the shift operators impose additional requirements
> that rule out more esoteric representations (like gray code
> ).


Both the C and the C++ standard explicitly require a pure binary
representation, which rules out greay code.

> I don't think that was intentional; rather, that the goal was just
> to allow the binary representations in use in the 1970's.


> IMHO opinion it would have been nice if we could just ditch
> the "ENIAC-support":


The problem is that it isn't just an issue for ENIAC. At least
one modern machine still uses signed magnitude, for example.

> like, require two's complement, require well-defined operator
> expressions, so on. But this has been discussed repeatedly and
> at length before. I think C++0x was the point of final freeze
> of adult features in C++, so to speak: since the change didn't
> happen with C++0x it will never happen, so we're stuck with
> the annoying behaviors along with the nicer ones...


There should be at least some changes in C++0x, because there
was a serious incompatibility between C and C++, and it meant
that C++ couldn't be implemented on one modern machine, where as
C could.

--
James Kanze


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-01-2011
On Apr 30, 1:19 am, Francis Glassborow
<(E-Mail Removed)> wrote:

[...]
> The problem for the OP is that whilst we can easily evaluate
> the number of bits in a type's object representation I know of
> no way to evaluate (you can look it up in the documentation)
> the number of bits in the value representation.


It should be possible exploiting xxx_MAX in some way. In C++11,
std::numeric_limits<T>::max() should also be usable.

--
James Kanze


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 
Reply With Quote
 
Matthias Hofmann
Guest
Posts: n/a
 
      05-02-2011

"James Kanze" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> On Apr 30, 12:25 am, "Alf P. Steinbach /Usenet"
> <(E-Mail Removed)> wrote:
>> * Matthias Hofmann, on 29.04.2011 02:55:

>
>>> So if I understand this correctly, for types "char" and
>>> "signed char", there may be bit patterns that do not
>>> represent numbers, unless "char" is an unsigned type?

>
>> Right.

>
> Not for plain char. In C++. (This is, I think, a difference
> between C and C++. C allows trapping bit patterns in plain
> char. Not that it makes a difference in practice.)


Yes, it does make a difference. Assuming that the standard allows a
conversion from a pointer to any object type to void* and back to char*, the
following two utility functions are legal:

// Converts a pointer of any non-const
// type to a non-const char pointer.
inline char* char_ptr( void* p ) throw()
{ return static_cast<char*>( p ); }

// Converts a pointer of any constant
// type to a constant char pointer.
inline const char* char_ptr( const void* p ) throw()
{ return static_cast<const char*>( p ); }

But what if the value of one byte accessed through such a char pointer is a
trap representation? Then iterating through the bytes of the underlying
object may cause the program to crash!

The answer seems to be using a pointer to unsigned char instead of plain
char, but there is a problem with that, too: 3.9.2/4 guarantees a char* to
have the same representation as a void*, but it does not give such a
guarantee to unsigned char*.

So how do you implement these two utility functions above? If you you a
plain char*, then you may have problems with bit patterns or sign expansion
errors, and if you use an unsigned char, then you have object representation
problems.

But if C++ does in fact not allow trapping bit patterns, then the problem is
solved and plain char should be used! So could you please refer me to the
corresponding section of the standard where I can find such a guarantee?

I can recommend the following links to earlier discussions on this newsgroup
for anyone who wants to delve deeper into this controversy:

About casting from T* to void* and from void* to char*:
http://groups.google.com/group/comp....54dcaab13a12c6

About the guarantee of being able to perform a static_cast from a pointer to
void to a pointer to any character type:
http://groups.google.com/group/comp....b1187f784d7274

--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-03-2011
On May 2, 8:13 pm, "Matthias Hofmann" <(E-Mail Removed)> wrote:
> "James Kanze" <(E-Mail Removed)> schrieb im
> Newsbeitragnews:(E-Mail Removed)...


> > On Apr 30, 12:25 am, "Alf P. Steinbach /Usenet"
> > <(E-Mail Removed)> wrote:
> >> * Matthias Hofmann, on 29.04.2011 02:55:


> >>> So if I understand this correctly, for types "char" and
> >>> "signed char", there may be bit patterns that do not
> >>> represent numbers, unless "char" is an unsigned type?


> >> Right.


> > Not for plain char. In C++. (This is, I think, a difference
> > between C and C++. C allows trapping bit patterns in plain
> > char. Not that it makes a difference in practice.)


> Yes, it does make a difference.


Not in practice, since no known implementation has ever had
trapping bit patterns in plain char. All known implementations
that don't use a straightforward 2's complement representation
make plain char unsigned.

> Assuming that the standard allows a conversion from a pointer
> to any object type to void* and back to char*, the following
> two utility functions are legal:


> // Converts a pointer of any non-const
> // type to a non-const char pointer.
> inline char* char_ptr( void* p ) throw()
> { return static_cast<char*>( p ); }


> // Converts a pointer of any constant
> // type to a constant char pointer.
> inline const char* char_ptr( const void* p ) throw()
> { return static_cast<const char*>( p ); }


> But what if the value of one byte accessed through such a char
> pointer is a trap representation? Then iterating through the
> bytes of the underlying object may cause the program to crash!


You can imagine implementations where such things might not
work. In practice, they don't exist.

> The answer seems to be using a pointer to unsigned char
> instead of plain char, but there is a problem with that, too:
> 3.9.2/4 guarantees a char* to have the same representation as
> a void*, but it does not give such a guarantee to unsigned
> char*.


That's probably an oversight. In general, the pointer
representations for the corresponding signed and unsigned types
should be the same. (In practice, they will be the same.)

> So how do you implement these two utility functions above?


In practice, they're fine as they stand (although I prefer
unsigned char).

> If you you a plain char*, then you may have problems with bit
> patterns or sign expansion errors, and if you use an unsigned
> char, then you have object representation problems.


In which real implementations?

> But if C++ does in fact not allow trapping bit patterns, then
> the problem is solved and plain char should be used! So could
> you please refer me to the corresponding section of the
> standard where I can find such a guarantee?


Not the standard, but compiler implementers want their compiler
to be used. If unsigned char* has a different representation
than char* (and I can't even imagine an architecture where this
wouldn't be the case), or if plain char actually does have
trapping representations (easily avoided by making plain char
unsigned), then the compiler won't be used.

--
James Kanze

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 
Reply With Quote
 
Matthias Hofmann
Guest
Posts: n/a
 
      05-14-2011
"Bart van Ingen Schenau" <(E-Mail Removed)> schrieb im Newsbeitrag news:ipr9ha$92o$(E-Mail Removed)...
>
> Matthias Hofmann Wrote:
>
>> I there actually a difference between the << and the >> operator with
>> respect to the number of positions that can be shifted?

>
> No, but the >> operator is not defined if the left-hand operand has a
> value
> < 0.


Really? So this is undefined behaviour? I thought that this would shift in
sign bits from the left, at least that's what happens on Microsoft Visual
C++ 6.0.

--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Smart or stupid? Tying textbox length to database column length Dan Manes ASP .Net 1 04-23-2006 10:57 PM
911...Need Help! : Length cannot be less than zero. Parameter name : length manmit.walia@gmail.com ASP .Net 2 01-10-2006 03:29 PM
left(string, length) or right(string, length)? Sam ASP .Net 3 02-17-2005 12:01 PM
System.ArgumentOutOfRangeException: Length cannot be less than zero. Parameter name: length =?Utf-8?B?SG96aQ==?= ASP .Net 1 06-01-2004 11:06 PM
How to get length of string? length() problems Mitchua Perl 5 07-17-2003 12:08 AM



Advertisments