Is there a portable/standard way of counting the
number of bits in a variable. The following for
statement works on all the machines I've tried:
#include <stdio.h>
int main(void) {
int n;
unsigned long int a;
for (n = 0, a = 1; a != 0; a <<= 1, n++) ;
printf("unsigned long int has %d bits.\n", n);
return 0;
}
Produces:
unsigned long int has 32 bits.
I don't want to depend on C standard built-in defines.
I want to check this during program execution.
--
Dale Dellutri <ddelQQQlutr@panQQQix.com> (lose the Q's)
|
|
0
|
|
|
|
Reply
|
ddelQQQlutr (156)
|
4/2/2009 3:31:41 PM |
|
On Thu, 2 Apr 2009 15:31:41 +0000 (UTC), Dale Dellutri
<ddelQQQlutr@panQQQix.com> wrote:
>Is there a portable/standard way of counting the
>number of bits in a variable.
With CHAR_BIT from limits.h and the sizeof operator.
[snip...snip...]
>I don't want to depend on C standard built-in defines.
>I want to check this during program execution.
If you don't trust the compiler to get sizeof right, why believe that it
will do anything else correctly?
--
Rich Webb Norfolk, VA
|
|
0
|
|
|
|
Reply
|
bbew.ar (758)
|
4/2/2009 3:50:26 PM
|
|
On Thu, 02 Apr 2009 11:50:26 -0400, Rich Webb <bbew.ar@mapson.nozirev.ten> wrote:
> On Thu, 2 Apr 2009 15:31:41 +0000 (UTC), Dale Dellutri
> <ddelQQQlutr@panQQQix.com> wrote:
> >Is there a portable/standard way of counting the
> >number of bits in a variable.
> With CHAR_BIT from limits.h and the sizeof operator.
> [snip...snip...]
> >I don't want to depend on C standard built-in defines.
> >I want to check this during program execution.
> If you don't trust the compiler to get sizeof right, why believe that it
> will do anything else correctly?
Probably because I knew about sizeof but not CHAR_BIT.
Thanks.
--
Dale Dellutri <ddelQQQlutr@panQQQix.com> (lose the Q's)
|
|
0
|
|
|
|
Reply
|
ddelQQQlutr (156)
|
4/2/2009 4:15:05 PM
|
|
Dale Dellutri wrote:
> Is there a portable/standard way of counting the
> number of bits in a variable. The following for
> statement works on all the machines I've tried:
>
> #include <stdio.h>
> int main(void) {
> int n;
> unsigned long int a;
>
> for (n = 0, a = 1; a != 0; a <<= 1, n++) ;
>
> printf("unsigned long int has %d bits.\n", n);
> return 0;
> }
>
> Produces:
> unsigned long int has 32 bits.
The method you've shown works for all unsigned integer
types, even for unsigned bit-fields. `CHAR_BIT * sizeof a'
is likely to work but ignores the nagging possibility of
padding bits (and, of course, won't work with bit-fields).
For signed types (including, possibly, `char'), you
must not attempt to shift a 1-bit into the sign position.
So I'd suggest initializing the variable to xxx_MAX and
right-shifting until you reach zero to count the value
bits, adding one if you also want to count the sign. I
can't think of a way to make this work for bit-fields,
since there's no xxx_MAX macro to appeal to. (It's
tempting to start at -1 and right-shift until you reach
zero, but right-shifting a negative integer is not well
defined -- on some machines you'd conclude that a signed
integer has an infinite number of bits!)
I can't think of a way to do this for floating-point
types. `CHAR_BIT * sizeof a' gives an upper bound, and
you could compute a lower bound from some <float.h> values,
and if they happened to agree you'd know. But if the
upper and lower bounds turned out different, I don't know
how you could refine them.
Pointer types look like a lost cause. Upper bound
via sizeof, but ... There's also a definitional problem:
In a pointer to a type that might have non-trivial alignment
requirements -- e.g., an `int*' with four-byte alignment --
are the low-order "must be zero" bits considered part of
the "value," or not?
> I don't want to depend on C standard built-in defines.
Why not? What problem are you trying to solve? Note
that even the unsigned-only solution requires you to know
how to write the name of the type, which implies that you
also know how to write the corresponding xxx_MAX macro.
`(int)(log(xxx_MAX + 1.0) / log(2.0) + 0.5)' should suffice.
> I want to check this during program execution.
You're in luck, because I can't think of a way to get
the bit count at compile time.
--
Eric.Sosman@sun.com
|
|
0
|
|
|
|
Reply
|
Eric.Sosman (4228)
|
4/2/2009 4:33:46 PM
|
|
On 2009-04-02, Dale Dellutri <ddelQQQlutr@panQQQix.com> wrote:
^^
You are a day late.
> unsigned long int has 32 bits.
>
> I don't want to depend on C standard built-in defines.
> I want to check this during program execution.
Why, do you suspect that this value can change at run-time?
For what other purpose would you defer to run time that which you can compute
at compile time?
|
|
0
|
|
|
|
Reply
|
kkylheku (2499)
|
4/2/2009 4:43:53 PM
|
|
Dale Dellutri wrote:
> #include <stdio.h>
> int main(void) {
> int n;
> unsigned long int a;
>
> for (n = 0, a = 1; a != 0; a <<= 1, n++) ;
>
> printf("unsigned long int has %d bits.\n", n);
> return 0;
> }
>
> Produces:
> unsigned long int has 32 bits.
That doesn't take into account possible padding bits.
Moreover, if you do something similar for a signed integer type,
you invoke undefined behavior because of the integer overflow.
Moreover, you must take into account integer promotions for types
with low rank.
Just stick with CHAR_BIT and sizeof.
> I don't want to depend on C standard built-in defines.
> I want to check this during program execution.
Why?
Yours,
Han from China
--
"Only entropy comes easy." -- Anton Chekhov
|
|
0
|
|
|
|
Reply
|
autistic-pedantry (1030)
|
4/2/2009 4:46:51 PM
|
|
Han from China <autistic-pedantry@comp.lang.c> writes:
> Dale Dellutri wrote:
>> #include <stdio.h>
>> int main(void) {
>> int n;
>> unsigned long int a;
>>
>> for (n = 0, a = 1; a != 0; a <<= 1, n++) ;
>>
>> printf("unsigned long int has %d bits.\n", n);
>> return 0;
>> }
>>
>> Produces:
>> unsigned long int has 32 bits.
>
> That doesn't take into account possible padding bits.
Why would you care? Number of bits in a variable kind of means how many
bit can be used.
>
> Moreover, if you do something similar for a signed integer type,
> you invoke undefined behavior because of the integer overflow.
>
> Moreover, you must take into account integer promotions for types
> with low rank.
>
> Just stick with CHAR_BIT and sizeof.
>
>> I don't want to depend on C standard built-in defines.
>> I want to check this during program execution.
>
> Why?
>
>
> Yours,
> Han from China
--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
|
|
0
|
|
|
|
Reply
|
rgrdev_ (1087)
|
4/2/2009 5:06:35 PM
|
|
Dale Dellutri wrote:
> Is there a portable/standard way of counting the
> number of bits in a variable.
There's number of bits in the 'object representation' and there's number
of bits in the 'value representation'. You need to decide first, which
one you need.
--
Best regards,
Andrey Tarasevich
|
|
0
|
|
|
|
Reply
|
andreytarasevich (1531)
|
4/2/2009 6:27:01 PM
|
|
On Apr 2, 9:27=A0pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
> Dale Dellutri wrote:
> > Is there a portable/standard way of counting the
> > number of bits in a variable. =A0
>
> There's number of bits in the 'object representation' and there's number
> of bits in the 'value representation'. You need to decide first, which
> one you need.
There's no such thing as a value representation. The object
representation of an integer has value bits, optional padding bits and
a sign bit, if the integer is signed. Special case are expressions
with unsigned char type, which can not have any padding bits.
Operations on values ignore the representation and thus padding bits
are not taken into account.
|
|
0
|
|
|
|
Reply
|
vippstar (1211)
|
4/3/2009 4:54:17 AM
|
|
Eric Sosman wrote:
> Dale Dellutri wrote:
> > Is there a portable/standard way of counting the
> > number of bits in a variable.
[...]
> > I want to check this during program execution.
>
> You're in luck, because I can't think of a way to get
> the bit count at compile time.
Someone posted a nifty macro a few months ago that determines how many
bits are needed to represent a given positive value that is a power of 2
minus one:
http://groups.google.com/group/comp.lang.c/browse_frm/thread/c48de16908e3ec82
> Hallvard B Furuseth once posted the following (which
> I've edited slightly due to line wrap issues)...
>
>� /* Number of bits in inttype_MAX, or in any (1<<b)-1
>� where 0 <= b < 3E+10 */
>� #define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) \
>� � /0x3fffffffL %0x3fffffffL *30 + \
>� � (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4 - \
>� � 12/((m)%31+3))
Seems to do the trick at compile-time. I don't think there's anything
gained by deferring it until run-time.
|
|
0
|
|
|
|
Reply
|
blargg.ei3 (369)
|
4/3/2009 8:23:51 AM
|
|
vippstar@gmail.com wrote:
> On Apr 2, 9:27 pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
> wrote:
>> Dale Dellutri wrote:
>>> Is there a portable/standard way of counting the
>>> number of bits in a variable.
>> There's number of bits in the 'object representation' and there's number
>> of bits in the 'value representation'. You need to decide first, which
>> one you need.
>
> There's no such thing as a value representation. ...
The standard disagrees: "If there are N value bits, each bit shall
represent a different power of 2 between 1 and 2N-1, so that objects of
that type shall be capable of representing values from 0 to 2N -1 using
a pure binary representation; this shall be known as the value
representation." (6.2.6.2p1).
Oddly enough, since 6.2.6.2p1 only describes unsigned integers, the
standard doesn't clarify whether sign bits should be considered to be
part of the value representation - I think they should. Since the
standard never uses the term again, this isn't any big problem. That's
probably why the term is not marked as a definition by putting it in
italics.
....
> Operations on values ignore the representation and thus padding bits
> are not taken into account.
The bit-wise operators (~, |, &, ^, <<, and >>) are all described as
operating on bits. Since those operations don't deal with padding bits,
that means that the bits they refer to make up the value representation
(at least for unsigned types - the terminology is unclear for signed types).
|
|
0
|
|
|
|
Reply
|
jameskuyper (5161)
|
4/3/2009 10:32:55 AM
|
|
On Apr 3, 1:32=A0pm, James Kuyper <jameskuy...@verizon.net> wrote:
> vipps...@gmail.com wrote:
> > On Apr 2, 9:27 pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
> > wrote:
> >> There's number of bits in the 'object representation' and there's numb=
er
> >> of bits in the 'value representation'.
>
> > There's no such thing as a value representation.
>
> The standard disagrees: "If there are N value bits, each bit shall
> represent a different power of 2 between 1 and 2N-1, so that objects of
> that type shall be capable of representing values from 0 to 2N -1 using
> a pure binary representation; this shall be known as the value
> representation." (6.2.6.2p1).
>
> Oddly enough, since 6.2.6.2p1 only describes unsigned integers, the
> standard doesn't clarify whether sign bits should be considered to be
> part of the value representation - I think they should. Since the
> standard never uses the term again, this isn't any big problem. That's
> probably why the term is not marked as a definition by putting it in
> italics.
Ah, thanks. I haven't read that before, (value representation). I
disagree though that 6.2.6.1p1 applies for signed integers or that the
value representation includes the sign bit, because other rules
described in 6.2.6.1p1 also do not apply for signed integers, for
example, "each bit shall represent a different power of 2 between 1
and 2N-1", while ones' complement -1 does not satisfy this condition.
Therefore, either signed integers do not have a value representation,
or the standard has a defect (incomplete). IMHO it is the latter.
> > Operations on values ignore the representation and thus padding bits
> > are not taken into account.
>
> The bit-wise operators (~, |, &, ^, <<, and >>) are all described as
> operating on bits. Since those operations don't deal with padding bits,
> that means that the bits they refer to make up the value representation
> (at least for unsigned types - the terminology is unclear for signed type=
s).
I'm not sure if the terminology is unclear, but to my experience,
surely smaller than yours, bit-wise operations on signed integers
indicated a bug in the code, and I've never encountered a problem
which required such operations on signed integers.
|
|
0
|
|
|
|
Reply
|
vippstar (1211)
|
4/3/2009 11:38:43 AM
|
|
vippstar@gmail.com wrote:
> On Apr 3, 1:32 pm, James Kuyper <jameskuy...@verizon.net> wrote:
....
>> Oddly enough, since 6.2.6.2p1 only describes unsigned integers, the
>> standard doesn't clarify whether sign bits should be considered to be
>> part of the value representation - I think they should. Since the
>> standard never uses the term again, this isn't any big problem. That's
>> probably why the term is not marked as a definition by putting it in
>> italics.
>
> Ah, thanks. I haven't read that before, (value representation). I
> disagree though that 6.2.6.1p1 applies for signed integers or that the
> value representation includes the sign bit, because other rules
> described in 6.2.6.1p1 also do not apply for signed integers, for
> example, "each bit shall represent a different power of 2 between 1
> and 2N-1", while ones' complement -1 does not satisfy this condition.
I think the sign bit should be part of the value representation, because
it plays a part in determining the value that is being represented.
> Therefore, either signed integers do not have a value representation,
> or the standard has a defect (incomplete). IMHO it is the latter.
I would consider the failure to specify a definition that applies to
signed integers a defect, were it not for the fact that the standard
never makes any use of the term, other than to define it.
>> The bit-wise operators (~, |, &, ^, <<, and >>) are all described as
>> operating on bits. Since those operations don't deal with padding bits,
>> that means that the bits they refer to make up the value representation
>> (at least for unsigned types - the terminology is unclear for signed types).
>
> I'm not sure if the terminology is unclear, but to my experience,
> surely smaller than yours, bit-wise operations on signed integers
> indicated a bug in the code, and I've never encountered a problem
> which required such operations on signed integers.
I would certainly agree that bit-wise operations should only be perform
on unsigned types. However, except for the shift operators, it is not
undefined behavior to apply them to signed integers, not even if the
signed integer has a negative value. The results are non-portable; but
not necessarily a bug.
|
|
0
|
|
|
|
Reply
|
jameskuyper (5161)
|
4/3/2009 12:36:43 PM
|
|
James Kuyper wrote:
> I would certainly agree that bit-wise operations should only be perform
> on unsigned types. However, except for the shift operators, it is not
> undefined behavior to apply them to signed integers, not even if the
> signed integer has a negative value. The results are non-portable; but
> not necessarily a bug.
The bitwise operators are capable of generating trap representations
when applied to int type expressions.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
4/3/2009 2:26:11 PM
|
|
Dale Dellutri wrote:
> Is there a portable/standard way of counting the
> number of bits in a variable. The following for
> statement works on all the machines I've tried:
>
> #include <stdio.h>
> int main(void) {
> int n;
> unsigned long int a;
>
> for (n = 0, a = 1; a != 0; a <<= 1, n++) ;
>
> printf("unsigned long int has %d bits.\n", n);
> return 0;
> }
>
> Produces:
> unsigned long int has 32 bits.
>
> I don't want to depend on C standard built-in defines.
> I want to check this during program execution.
>
I understand that this is an assignment in colleges/universities, since
I had to do this one too.
You are doing just fine, you should not have portability problem with
this solution.
|
|
0
|
|
|
|
Reply
|
dfighter2 (43)
|
4/4/2009 3:40:16 PM
|
|
|
14 Replies
26 Views
(page loaded in 0.24 seconds)
Similiar Articles: size of a derived type containing pointers... - comp.lang.fortran ...There is currently no portable standard-conforming way. ... macro CHAR_BIT indicating the number of bits in a ... much less f2008, you can't necessarily count ... Difference between passing a number and a variable to a subroutine ...... distinguishes between passing a variable and actual numbers ... Yes, you can (usually) count on them to work; the standard says they ... extended and/or modified a little bit ... Integers on 64-bit machines - comp.compilers... preferable to still leave the standard integer type ("int") 32-bit ... Even better than a small fixed number ... code for reading and writing variables of different byte count. Watchdog thread syncronisation with semphores? - comp.unix ...It uses Mutexes, joins and condition variables ... On reflection it does seem a bit ott, but i thought the correct way to handle ... and palm it of to a new port number with a ... improve strlen - comp.lang.asm.x86... operations and very small number of local variables, the ... do you see people writing standard C++ programs the way you ... trivial little (and often non-portable) code this way ... Reading an unformatted file - comp.lang.fortran... to have in some more portable way. Note: 32 bit D ... The standard provides no guarantee of last-bit accuracy. ... * The count is the number of bytes in the ... Converting number to std::string ("itoa()" ) - comp.lang.c++ ...... you recommend is the best way to construct a std::string from a numerical variable ... There is a standard portable way of doing such ... But let's continue a bit ... input & output in assembly - comp.lang.asm.x86in 16-bit assembly is there any way to accept numbers as input and display them ... usually used to provide "portable" access ... routine (we now need _two_ "count" variables - in ... [comp.publish.cdrom] CD-Recordable FAQ, Part 1/4 - comp.publish ...Archive-name: cdrom/cd-recordable/part1 Posting-Frequency: monthly Last-modified: 2008/10/09 Version: 2.71 Send corrections and updates to And... Size of Integer , long Integer, Long double - comp.lang.c++ ...I don't see any way to create table in usenet so used my own variable- width font. ... comp.lang.java.help... variables int count ... signed integer to a 16-bit hex number ... Create an HTML report from this dataset - comp.soft-sys.sas ...... that has anywhere from 1-5 class variables and a count variable. ... Is there a way to do this with PROC REPORT ? PROC FREQ ? ... and excel lost date format - comp.soft ..... 32-bit ... Math logic - comp.lang.asm.x86are millisecond in a 64 bit variable or in one ... shifts of ints by sizeof(int)*CHAR_BIT or more per the C/C++ standard ... periods, while the > remaining 48 bits is the number ... 64 bit integer - comp.lang.c++.moderated... cannot be included by any of the >standard includes). Actually the correct way ... years, it is still not possible to count ... for my integral type, not the number of bits ... Random number in Fortran 90/95 - comp.lang.fortran... to save the seed to avoid standard initialisation. You can try this way. ... IMPLICIT NONE ! ----- variables for portable ... And if we want 64-bit random numbers, with B=2 ... fork() race in SIGCHLD handler - comp.unix.programmerOne (maybe "the") standard way to synchronize between ... it had assigned the child process number to the global variable ... are writing ONLY FOR LINUX, you cannot count ... Bit Twiddling Hacks - Computer Graphics at Stanford University... faster but less portable method that doesn't depend on the bits ... Brian Kernighan's way unsigned int v; // count the number of bits ... on individual bits. The variable x ... Best algorithm to count the number of set bits in a 32-bit integer ...... known as 'parallel' or 'variable ... unsigned int v; // count the number of bits set in v ... If someone can figure a way to make the "Hacker's Delight" algorithm portable ... 7/12/2012 4:28:34 PM
|