By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,993 Members | 1,947 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,993 IT Pros & Developers. It's quick & easy.

to calculate bitsize of a byte

P: n/a
I am reading "Joel on Software" these days, and am in stuck with the
question of "how to calculate bitsize of a byte" which is listed as one
of the basic interview questions in Joel's book. Anyone could give some
ideas?I am expecting your reply.
David.

Feb 21 '06 #1
Share this Question
Share on Google+
96 Replies


P: n/a
david ullua wrote:
I am reading "Joel on Software" these days, and am in stuck with the
question of "how to calculate bitsize of a byte" which is listed as
one of the basic interview questions in Joel's book. Anyone could give
some ideas?I am expecting your reply.
David.


That's easy:

#include <limits.h>

int bitsize = CHAR_BIT;

--
BR, Vladimir

What is love but a second-hand emotion?
-- Tina Turner

Feb 21 '06 #2

P: n/a
david ullua wrote:
I am reading "Joel on Software" these days, and am in stuck with the
question of "how to calculate bitsize of a byte" which is listed as one
of the basic interview questions in Joel's book. Anyone could give some
ideas?I am expecting your reply.


The terms 'byte' and 'char' refer to (almost) the same thing in C.[1]
The predefined macro CHAR_BIT contains the size in bits of a char, and
therefore of a byte. The computation of the bitsize of a byte is simply
/* ... other code ... */
CHAR_BIT;
/* ... other code ... */
That wasn't so hard, was it?

[1] Some pedants will tell you that a 'char' is an object of the type
'char', while a 'byte' is the storage taken by such an object. It is
doubtful that such questions will have any real world impact on you.
Feb 21 '06 #3

P: n/a
Thanks for both of your reply.
I take a look at limits.h and other head files, there is really
something need to be read.
Before i knew CHAR_BIT is a defined value, I wrote the following
snippet to do the job:
(now i realize it is not neccessary)
char c = '\01';
int i=0;
do
{
i++;
printf("%d:%x(dex)\n",i,c);
c = c<<1;
}while(c>0);
printf("bit count in a byte:%d",i);

Feb 21 '06 #4

P: n/a

"david ullua" <da*********@gmail.com> wrote in message
news:11********************@g14g2000cwa.googlegrou ps.com...
I am reading "Joel on Software" these days, and am in stuck with the
question of "how to calculate bitsize of a byte" which is listed as one
of the basic interview questions in Joel's book. Anyone could give some
ideas?I am expecting your reply.


David,

You are the only one to get it correct so far. Martin and Vladimir both
failed. The question was how to _calculate_ the bits in a byte. Looking up
CHAR_BIT is not a calculation.
Rod Pemberton
Feb 21 '06 #5

P: n/a
Hi, Rod,

Thanks for your reply. Martin and Vladimir have given a solution to
find bit size of byte. Maybe Joe was not intended to get such anwser
from interviewee, it is still an efficient way :).

I wander whether there exists such case when we don't know the bit size
of byte in a machine but we need to calculate it in programming
language? It's just like kidding, since we don't know bytesize in the
machine, how could we know which programming lanugage would work on it?

Feb 21 '06 #6

P: n/a
Hi, Rod,

Martin and Vladimir has given a shorten method to find bit size of a
byte in c :). I think maybe Joe was not intended get an answer of
calculation, not looking up in an included file.

In programming language like C, compiler may set CHAR_BIT predefined.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language. The case's just like kidding, since we don't know bits of
CPU, how could programming language would work on it?

Feb 21 '06 #7

P: n/a

david ullua wrote:
Hi, Rod,

Thanks for your reply. Martin and Vladimir have given a solution to
find bit size of byte. Maybe Joe was not intended to get such anwser
from interviewee, it is still an efficient way :).

I wander whether there exists such case when we don't know the bit size
of byte in a machine but we need to calculate it in programming
language? It's just like kidding, since we don't know bytesize in the
machine, how could we know which programming lanugage would work on it?


Oh, alright...

#include <limits.h>

int bytesize = 1 * CHAR_BIT;

Does this qualify as calculation?

If you have a compliant Standard C implementation this has to work, and
it won't fail you.

There are batter ways of testing algorithmic skills in an interview
than contriving something like this.

PS
Please quote what you're replying to. Many people can't see the whole
thread.

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>

--
BR, Vladimir

Feb 21 '06 #8

P: n/a
david ullua wrote:
Hi, Rod,

Martin and Vladimir has given a shorten method to find bit size of a
byte in c :). I think maybe Joe was not intended get an answer of
calculation, not looking up in an included file.

In programming language like C, compiler may set CHAR_BIT predefined.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language. The case's just like kidding, since we don't know bits of
CPU, how could programming language would work on it?


To complicate matters, char is not required by the C standard to be the
machine "byte". It is only required to be at least 8 bits. And a
machine "byte" is not always 8 bits. And some ancient beasts even
enables the programmer to specify how many bits are in a byte. So on
those machines (I believe Unisys was one) you "defined" how many bits
was in a byte rather than test it.

Your code fails on a machine with 6 bit bytes and a C compiler with 12
bit chars (remember 6 bit bytes are not allowed by the standard).

So, given that it can't strictly be done in C the only "portable"
answer is to use an electron microscope to count the number of
flip-flops in a register used in byte oriented operations. Once you go
into that territory (if you have $$, there are several companies in
Taiwan willing to do it for you) then this problem is no longer
relevant to C and is therefore OT here.

Note that even if you do decide to go the electron microscope route
you'll still fail on machines which allows the programmer to define the
size of "byte" since it really is up to the programmer, not an inherent
property of the machine.

Feb 21 '06 #9

P: n/a
Rod Pemberton wrote:

You are the only one to get it correct so far. Martin and Vladimir both
failed. The question was how to _calculate_ the bits in a byte. Looking up
CHAR_BIT is not a calculation.


Sure it is. Grow up.
Feb 21 '06 #10

P: n/a
On 21 Feb 2006 02:26:52 -0800, "sl*******@yahoo.com"
<sl*******@gmail.com> wrote:
david ullua wrote:
Hi, Rod,

Martin and Vladimir has given a shorten method to find bit size of a
byte in c :). I think maybe Joe was not intended get an answer of
calculation, not looking up in an included file.

In programming language like C, compiler may set CHAR_BIT predefined.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language. The case's just like kidding, since we don't know bits of
CPU, how could programming language would work on it?


To complicate matters, char is not required by the C standard to be the
machine "byte". It is only required to be at least 8 bits. And a
machine "byte" is not always 8 bits. And some ancient beasts even
enables the programmer to specify how many bits are in a byte. So on
those machines (I believe Unisys was one) you "defined" how many bits
was in a byte rather than test it.


In that case, the definition of "byte" has to be a part of the problem
specification.

--
Al Balmer
Sun City, AZ
Feb 21 '06 #11

P: n/a
On 21 Feb 2006 01:02:30 -0800, "david ullua" <da*********@gmail.com>
wrote:
Hi, Rod,

Martin and Vladimir has given a shorten method to find bit size of a
byte in c :). I think maybe Joe was not intended get an answer of
calculation, not looking up in an included file.

In programming language like C, compiler may set CHAR_BIT predefined.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language. The case's just like kidding, since we don't know bits of
CPU, how could programming language would work on it?


Consider the possibility that you might want to calculate the size of
a character at run-time.

--
Al Balmer
Sun City, AZ
Feb 21 '06 #12

P: n/a
On 2006-02-21, Al Balmer <al******@att.net> wrote:
On 21 Feb 2006 01:02:30 -0800, "david ullua" <da*********@gmail.com>
wrote:
Hi, Rod,

Martin and Vladimir has given a shorten method to find bit size of a
byte in c :). I think maybe Joe was not intended get an answer of
calculation, not looking up in an included file.

In programming language like C, compiler may set CHAR_BIT predefined.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language. The case's just like kidding, since we don't know bits of
CPU, how could programming language would work on it?


Consider the possibility that you might want to calculate the size of
a character at run-time.


That is a lot easier than a BYTE isnt it?

Just left shift a bit x times on a defined "char" and detect it zeroing.

--
Remove evomer to reply
Feb 21 '06 #13

P: n/a
On 2006-02-21, Richard G. Riley <rg***********@gmail.com> wrote:
On 2006-02-21, Al Balmer <al******@att.net> wrote:
On 21 Feb 2006 01:02:30 -0800, "david ullua" <da*********@gmail.com>
wrote:
Hi, Rod,

Martin and Vladimir has given a shorten method to find bit size of a
byte in c :). I think maybe Joe was not intended get an answer of
calculation, not looking up in an included file.

In programming language like C, compiler may set CHAR_BIT predefined.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language. The case's just like kidding, since we don't know bits of
CPU, how could programming language would work on it?


Consider the possibility that you might want to calculate the size of
a character at run-time.


That is a lot easier than a BYTE isnt it?

Just left shift a bit x times on a defined "char" and detect it zeroing.


Except for overflow. And if this _does_ work, it will result in the same
answer as CHAR_BIT.
Feb 21 '06 #14

P: n/a
david ullua wrote:
Thanks for both of your reply.


Both who? See below.

Brian

--
Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.
Feb 21 '06 #15

P: n/a
On 2006-02-21, Jordan Abel <ra*******@gmail.com> wrote:
On 2006-02-21, Richard G. Riley <rg***********@gmail.com> wrote:
On 2006-02-21, Al Balmer <al******@att.net> wrote:
On 21 Feb 2006 01:02:30 -0800, "david ullua" <da*********@gmail.com>
wrote:

Hi, Rod,

Martin and Vladimir has given a shorten method to find bit size of a
byte in c :). I think maybe Joe was not intended get an answer of
calculation, not looking up in an included file.

In programming language like C, compiler may set CHAR_BIT predefined.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language. The case's just like kidding, since we don't know bits of
CPU, how could programming language would work on it?

Consider the possibility that you might want to calculate the size of
a character at run-time.


That is a lot easier than a BYTE isnt it?

Just left shift a bit x times on a defined "char" and detect it zeroing.


Except for overflow. And if this _does_ work, it will result in the same
answer as CHAR_BIT.


I would hope so : I was more referring to the fact that a lot of
people wanted to muddy the waters with run time calculations of byte
size as opposed to compile time constants. "char" is easier because it
is a defined type so doing the bit shift really can and does work
without any worries of "purity" ...
--
Remove evomer to reply
Feb 21 '06 #16

P: n/a

"Martin Ambuhl" <ma*****@earthlink.net> wrote in message
news:AR*****************@newsread2.news.atl.earthl ink.net...
Rod Pemberton wrote:

You are the only one to get it correct so far. Martin and Vladimir both
failed. The question was how to _calculate_ the bits in a byte. Looking up CHAR_BIT is not a calculation.


Sure it is. Grow up.


The OP also said it was an _interview_ question. If it came from Microsoft,
you'd be expected to _calculate_ it, not look it up. If you fail a simple
example like this on a job interview, your chances of getting the job
decrease. That's reality, whether you think it's immature or not.
Rod Pemberton
Feb 21 '06 #17

P: n/a
"Richard G. Riley" wrote:
On 2006-02-21, Al Balmer <al******@att.net> wrote:
.... snip ...
Consider the possibility that you might want to calculate the
size of a character at run-time.


That is a lot easier than a BYTE isnt it?

Just left shift a bit x times on a defined "char" and detect it
zeroing.


You just created undefined or implementation defined behaviour.
You need to use an unsigned char, and need to store the shifted
value after each operation. Probably means a volatile unsigned
char. Of course the use of CHAR_BIT can't be allowed.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Feb 21 '06 #18

P: n/a
CBFalconer wrote:

"Richard G. Riley" wrote:
On 2006-02-21, Al Balmer <al******@att.net> wrote:
... snip ...
Consider the possibility that you might want to calculate the
size of a character at run-time.


That is a lot easier than a BYTE isnt it?

Just left shift a bit x times on a defined "char" and detect it
zeroing.


You just created undefined or implementation defined behaviour.
You need to use an unsigned char, and need to store the shifted
value after each operation. Probably means a volatile unsigned
char. Of course the use of CHAR_BIT can't be allowed.


Define an unsigned char with a value of -1,
and count the right shifts until zero.

--
pete
Feb 21 '06 #19

P: n/a

"david ullua" <da*********@gmail.com> wrote in message
news:11********************@f14g2000cwb.googlegrou ps.com...
Thanks for both of your reply.
I take a look at limits.h and other head files, there is really
something need to be read.
Before i knew CHAR_BIT is a defined value, I wrote the following
snippet to do the job:
(now i realize it is not neccessary)
char c = '\01';
int i=0;
do
{
i++;
printf("%d:%x(dex)\n",i,c);
c = c<<1;
}while(c>0);
printf("bit count in a byte:%d",i);


There's a bug. If char is signed, the c>0 will stop one bit short. Try c!=0.

-Walter Bright
www.digitalmars.com C, C++, D programming language compilers.
Feb 21 '06 #20

P: n/a
"Richard G. Riley" <rg***********@gmail.com> writes:
On 2006-02-21, Jordan Abel <ra*******@gmail.com> wrote:
On 2006-02-21, Richard G. Riley <rg***********@gmail.com> wrote:
On 2006-02-21, Al Balmer <al******@att.net> wrote: [...] Consider the possibility that you might want to calculate the size of
a character at run-time.

That is a lot easier than a BYTE isnt it?

Just left shift a bit x times on a defined "char" and detect it zeroing.


Except for overflow. And if this _does_ work, it will result in the same
answer as CHAR_BIT.


I would hope so : I was more referring to the fact that a lot of
people wanted to muddy the waters with run time calculations of byte
size as opposed to compile time constants. "char" is easier because it
is a defined type so doing the bit shift really can and does work
without any worries of "purity" ...


If char is signed, a left shift that overflows invokes undefined
behavior. You can reliably shift an *unsigned* char to determine the
number of bits.

#include<stdio.h>
#include<limits.h>
int main(void)
{
int bits = 0;
unsigned char x = 1;
while (x != 0) {
x <<= 1;
bits ++;
}
printf("bits = %d\n", bits);
if (bits != CHAR_BIT) {
printf("CHAR_BIT = %d (OOPS!)\n", CHAR_BIT);
}
return 0;
}

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 21 '06 #21

P: n/a
Rod Pemberton failed his job interview when he wrote:
"Martin Ambuhl" <ma*****@earthlink.net> wrote in message
news:AR*****************@newsread2.news.atl.earthl ink.net...
Rod Pemberton wrote:
You are the only one to get it correct so far. Martin and
Vladimir both failed. The question was how to _calculate_ the
bits in a byte. Looking up CHAR_BIT is not a calculation.
Sure it is. Grow up.
The OP also said it was an _interview_ question. If it came from Microsoft,
you'd be expected to _calculate_ it, not look it up. If you fail a simple
example like this on a job interview, your chances of getting the job
decrease. That's reality, whether you think it's immature or not.


If you create a program to satisfy your childish idea of what
"calculate" means, the interviewer will know that you neither know C nor
do you have a clue about how to program. Successful programming
involves not doing extra work, spinning your wheels, just to avoid using
the obviously available.
Feb 21 '06 #22

P: n/a
david ullua a écrit :
I am reading "Joel on Software" these days, and am in stuck with the
question of "how to calculate bitsize of a byte" which is listed as one
of the basic interview questions in Joel's book. Anyone could give some
ideas?I am expecting your reply.


Quite simple.
1 - Include <limits.h>
2 - printout the value of CHAR_BIT.
Done.

--
C is a sharp tool
Feb 21 '06 #23

P: n/a
david ullua a écrit :
Thanks for both of your reply.
I take a look at limits.h and other head files, there is really
something need to be read.


/Your/ C-book needs to be read from cover to cover. every 6 month.

--
C is a sharp tool
Feb 21 '06 #24

P: n/a
Keith Thompson wrote:
If char is signed, a left shift that overflows invokes undefined
behavior. You can reliably shift an *unsigned* char to determine the
number of bits.


Not if UCHAR_MAX equals INT_MAX, which it may.

--
pete
Feb 21 '06 #25

P: n/a
On 2006-02-21, pete <pf*****@mindspring.com> wrote:
Keith Thompson wrote:
If char is signed, a left shift that overflows invokes undefined
behavior. You can reliably shift an *unsigned* char to determine the
number of bits.


Not if UCHAR_MAX equals INT_MAX, which it may.


Eh?

No, because you can keep left-shifting the unsigned char and the
behavior of an unsigned type on "overflow" is perfectly well-defined

what does int have to do with anything?
Feb 21 '06 #26

P: n/a
"sl*******@yahoo.com" <sl*******@gmail.com> wrote in message
news:11********************@g43g2000cwa.googlegrou ps.com...
To complicate matters, char is not required by the C standard to be the
machine "byte". It is only required to be at least 8 bits. And a
machine "byte" is not always 8 bits. And some ancient beasts even
enables the programmer to specify how many bits are in a byte. So on
those machines (I believe Unisys was one) you "defined" how many bits
was in a byte rather than test it.

So you are saying that there are two bytes: the "machine byte" and the "C
implementation byte"? I assume that because the C standard clearly states
that char is equivalent to byte.
Your code fails on a machine with 6 bit bytes and a C compiler with 12
bit chars (remember 6 bit bytes are not allowed by the standard).


How can such as system exist then?
Feb 21 '06 #27

P: n/a
Jordan Abel wrote:

On 2006-02-21, pete <pf*****@mindspring.com> wrote:
Keith Thompson wrote:
If char is signed, a left shift that overflows invokes undefined
behavior. You can reliably shift an *unsigned* char to determine the
number of bits.


Not if UCHAR_MAX equals INT_MAX, which it may.


Eh?

No, because you can keep left-shifting the unsigned char and the
behavior of an unsigned type on "overflow" is perfectly well-defined

what does int have to do with anything?


Look up "integer promotions"

If INT_MAX is greater than or equal to UCHAR_MAX
then the shift operator will cause the unsigned char expression
to be promoted to type int.

If INT_MAX is equal to UCHAR_MAX,
then the final iteration is equivalent to
byte = INT_MAX << 1

unsigned short has the same problem.
You can't portably increment unsigned types until they roll over,
if they are lower ranking than int.

--
pete
Feb 21 '06 #28

P: n/a

"david ullua" wrote:
I am reading "Joel on Software" these days, and am in stuck with the
question of "how to calculate bitsize of a byte" which is listed as one
of the basic interview questions in Joel's book. Anyone could give some
ideas?I am expecting your reply.
David.


Try this:

unsigned char x = 0;
unsigned int y = INT_MAX; /*assuming less than MAX_INT bits*/

while( y )
{
x |= 1;
x <<= 1
}

while( x >>= 1 )
y++;

now y should give the number of bits in a char...

regards
John.
Feb 21 '06 #29

P: n/a
stathis gotsis wrote:
"sl*******@yahoo.com" <sl*******@gmail.com> wrote in message
news:11********************@g43g2000cwa.googlegrou ps.com...
To complicate matters, char is not required by the C standard to be the
machine "byte". It is only required to be at least 8 bits. And a
machine "byte" is not always 8 bits. And some ancient beasts even
enables the programmer to specify how many bits are in a byte. So on
those machines (I believe Unisys was one) you "defined" how many bits
was in a byte rather than test it.

So you are saying that there are two bytes: the "machine byte" and the "C
implementation byte"? I assume that because the C standard clearly states
that char is equivalent to byte.


Yes, which is why it's best to use the term 'byte' in the C language
sense,
and terms like octet or machine word for other senses.
Your code fails on a machine with 6 bit bytes and a C compiler with 12
bit chars (remember 6 bit bytes are not allowed by the standard).


How can such as system exist then?


The same way a C90 program can construct 64-bit pseudo ints from two
unsigned longs (which are only guaranteed to be at least 32-bits each.)

--
Peter

Feb 21 '06 #30

P: n/a
Rod Pemberton wrote:
... The question was how to _calculate_ the bits in a byte. Looking up
CHAR_BIT is not a calculation.


So it's not possible to enter 8 on a calculator, hit enter, and expect
to
see 8 as the result? My 20 year old pocket calculator must really be
out of date...

--
Peter

Feb 21 '06 #31

P: n/a
On 2006-02-21, pete <pf*****@mindspring.com> wrote:
Jordan Abel wrote:

On 2006-02-21, pete <pf*****@mindspring.com> wrote:
> Keith Thompson wrote:
>
>> If char is signed, a left shift that overflows invokes undefined
>> behavior. You can reliably shift an *unsigned* char to determine the
>> number of bits.
>
> Not if UCHAR_MAX equals INT_MAX, which it may.
Eh?

No, because you can keep left-shifting the unsigned char and the
behavior of an unsigned type on "overflow" is perfectly well-defined

what does int have to do with anything?


Look up "integer promotions"

If INT_MAX is greater than or equal to UCHAR_MAX then the shift
operator will cause the unsigned char expression to be promoted to
type int.


You're assuming that the right-hand operand is of type int.
If INT_MAX is equal to UCHAR_MAX,
then the final iteration is equivalent to
byte = INT_MAX << 1

unsigned short has the same problem.
You can't portably increment unsigned types until they roll over,
if they are lower ranking than int.


Why not?

unsigned short x = 1;

x <<= (unsigned short)1;
/* 15 more or however many times */

or even

x <<= 1U; [it'll promote to unsigned int and safely drop back down]
Feb 21 '06 #32

P: n/a
pete wrote:
If INT_MAX is equal to UCHAR_MAX,
then the final iteration is equivalent to
byte = INT_MAX << 1

unsigned short has the same problem.
You can't portably increment unsigned types until they roll over,
if they are lower ranking than int.


But you can do...

my_unsigned_short += 1u;

What Keith needed was...

x *= 2u;

--
Peter

Feb 21 '06 #33

P: n/a
Jordan Abel wrote:
On 2006-02-21, pete <pf*****@mindspring.com> wrote:
Jordan Abel wrote:
On 2006-02-21, pete <pf*****@mindspring.com> wrote:
> ... Not if UCHAR_MAX equals INT_MAX, which it may.

Eh?

No, because you can keep left-shifting the unsigned char and the
behavior of an unsigned type on "overflow" is perfectly well-defined

what does int have to do with anything?
Look up "integer promotions"

If INT_MAX is greater than or equal to UCHAR_MAX then the shift
operator will cause the unsigned char expression to be promoted to
type int.


You're assuming that the right-hand operand is of type int.


No. The integral promotion is only relevant to the left hand operand of
shift
expressions.
If INT_MAX is equal to UCHAR_MAX,
then the final iteration is equivalent to
byte = INT_MAX << 1

unsigned short has the same problem.
You can't portably increment unsigned types until they roll over,
if they are lower ranking than int.


Why not?

unsigned short x = 1;

x <<= (unsigned short)1;
/* 15 more or however many times */


Because if USHRT_MAX <= INT_MAX, then you'll eventually be doing...

x = (INT_MAX/2+1) << 1

or even

x <<= 1U; [it'll promote to unsigned int and safely drop back down]


No, the two operands of shift operators are not subject to arithmetic
promotion.

--
Peter

Feb 21 '06 #34

P: n/a
On 2006-02-21, Peter Nilsson <ai***@acay.com.au> wrote:
Jordan Abel wrote:
On 2006-02-21, pete <pf*****@mindspring.com> wrote:
> Jordan Abel wrote:
>> On 2006-02-21, pete <pf*****@mindspring.com> wrote:
>> > ... Not if UCHAR_MAX equals INT_MAX, which it may.
>>
>> Eh?
>>
>> No, because you can keep left-shifting the unsigned char and the
>> behavior of an unsigned type on "overflow" is perfectly well-defined
>>
>> what does int have to do with anything?
>
> Look up "integer promotions"
>
> If INT_MAX is greater than or equal to UCHAR_MAX then the shift
> operator will cause the unsigned char expression to be promoted to
> type int.


You're assuming that the right-hand operand is of type int.


No. The integral promotion is only relevant to the left hand operand
of shift expressions.


Then what could cause the left-hand operand (being, as established,
unsigned char) to be promoted to int at all? Is there some magical "all
types narrower than int get promed to int all the time no matter what"
rule i haven't heard about?

It's not clear how

x {is unsigned short} <<= 1U

causes anything to be promoted to any signed type.
> If INT_MAX is equal to UCHAR_MAX,
> then the final iteration is equivalent to
> byte = INT_MAX << 1
>
> unsigned short has the same problem.
> You can't portably increment unsigned types until they roll over,
> if they are lower ranking than int.


Why not?

unsigned short x = 1;

x <<= (unsigned short)1;
/* 15 more or however many times */


Because if USHRT_MAX <= INT_MAX, then you'll eventually be doing...

x = (INT_MAX/2+1) << 1


I assume you mean

x = (unsigned short)(INT_MAX/2+1) << (unsigned short)1

or even

x <<= 1U; [it'll promote to unsigned int and safely drop back down]


No, the two operands of shift operators are not subject to arithmetic
promotion.


But your entire POINT rides on having it be promoted to signed int if
you use 1 instead of 1U or (unsigned short)1!
Feb 21 '06 #35

P: n/a
"Walter Bright" <wa****@nospamm-digitalmars.com> writes:
"david ullua" <da*********@gmail.com> wrote in message
news:11********************@f14g2000cwb.googlegrou ps.com...
Thanks for both of your reply.
I take a look at limits.h and other head files, there is really
something need to be read.
Before i knew CHAR_BIT is a defined value, I wrote the following
snippet to do the job:
(now i realize it is not neccessary)
char c = '\01';
int i=0;
do
{
i++;
printf("%d:%x(dex)\n",i,c);
c = c<<1;
}while(c>0);
printf("bit count in a byte:%d",i);


There's a bug. If char is signed, the c>0 will stop one bit short. Try c!=0.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If he's (un)lucky...

-Micah
Feb 21 '06 #36

P: n/a
"Peter Nilsson" <ai***@acay.com.au> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
stathis gotsis wrote:
"sl*******@yahoo.com" <sl*******@gmail.com> wrote in message
news:11********************@g43g2000cwa.googlegrou ps.com...
To complicate matters, char is not required by the C standard to be the machine "byte". It is only required to be at least 8 bits. And a
machine "byte" is not always 8 bits. And some ancient beasts even
enables the programmer to specify how many bits are in a byte. So on
those machines (I believe Unisys was one) you "defined" how many bits
was in a byte rather than test it.

So you are saying that there are two bytes: the "machine byte" and the "C
implementation byte"? I assume that because the C standard clearly states that char is equivalent to byte.


Yes, which is why it's best to use the term 'byte' in the C language
sense,
and terms like octet or machine word for other senses.


Thank you for your answer.
Your code fails on a machine with 6 bit bytes and a C compiler with 12
bit chars (remember 6 bit bytes are not allowed by the standard).


How can such as system exist then?


The same way a C90 program can construct 64-bit pseudo ints from two
unsigned longs (which are only guaranteed to be at least 32-bits each.)


I misread the previous poster's comment. Yes, such a system can exist. I
thought the OP referred to the implementation's byte size, as oppposed to
the machine's. One cannot determine the machine's byte size through C
because a C implementation may hide the HW details.
Feb 21 '06 #37

P: n/a
Martin Ambuhl <ma*****@earthlink.net> writes:
Rod Pemberton failed his job interview when he wrote:
"Martin Ambuhl" <ma*****@earthlink.net> wrote in message
news:AR*****************@newsread2.news.atl.earthl ink.net...
Rod Pemberton wrote:
You are the only one to get it correct so far. Martin and Vladimir
both failed. The question was how to _calculate_ the bits in a
byte. Looking up CHAR_BIT is not a calculation.Sure it is. Grow up.

The OP also said it was an _interview_ question. If it came from Microsoft,
you'd be expected to _calculate_ it, not look it up. If you fail a simple
example like this on a job interview, your chances of getting the job
decrease. That's reality, whether you think it's immature or not.


If you create a program to satisfy your childish idea of what
"calculate" means, the interviewer will know that you neither know C
nor do you have a clue about how to program. Successful programming
involves not doing extra work, spinning your wheels, just to avoid
using the obviously available.


If an interviewer asked me how to calculate the number of bits in a
byte in C, I'd say "look at CHAR_BIT in <limits.h>". If he says, "Ok,
how would you do it without using CHAR_BIT", *then* I'd think about
how to do it by shifting bits. If I'm penalized for giving a correct
answer, it's likely not someplace I want to work.

Conceivably someone might try to guess what the interviewer means and
try to give the answer he wants, avoiding the simple and correct
answer, but that approach is likely to backfire; it's just as likely
the interviewer wanted to see whether I know about CHAR_BIT. In any
case, interview strategies beyond giving correct answers are beyond
the scope of this newsgroup.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 21 '06 #38

P: n/a
Jordan Abel wrote:
On 2006-02-21, Peter Nilsson <ai***@acay.com.au> wrote:
... The integral promotion is only relevant to the left hand operand
of shift expressions.
Then what could cause the left-hand operand (being, as established,
unsigned char) to be promoted to int at all? Is there some magical "all
types narrower than int get promed to int all the time no matter what"
rule i haven't heard about?


Not "no matter what", but generally they do get promoted as per
6.3.1.1p2.
The fact of 6.3.1.1p3 makes the integer promotion of the right hand
operand (of a shift operator) incidental.
It's not clear how

x {is unsigned short} <<= 1U

causes anything to be promoted to any signed type.


In cases where USHRT_MAX <= INT_MAX, we have...

x <<= 1u;
x = x << 1u;
x = ((int) x) << 1u;

....all being identical. The u suffix in 1u is irrelevant here, it's the
integral
promotion of x from unsigned short to int that may occur.

If, for the same premice, we instead have...

x += 1u;
x = x + 1u;

Then arithmetic conversion occurs on top of the integral promotion...

x = (unsigned) (int) x + 1u;

Whilst arithmetic conversion applies to binary +, it does not apply to
<<.

<snip>
Because if USHRT_MAX <= INT_MAX, then you'll eventually be doing...

x = (INT_MAX/2+1) << 1


I assume you mean

x = (unsigned short)(INT_MAX/2+1) << (unsigned short)1


Given the initial premice, they have the same semantics. Even the
explicit cast to (unsigned short) will not prevent integral promotion
from applying to the left operand.
or even

x <<= 1U; [it'll promote to unsigned int and safely drop back down]


No, the two operands of shift operators are not subject to arithmetic
promotion.


But your entire POINT rides on having it be promoted to signed int if
you use 1 instead of 1U or (unsigned short)1!


No. I think you haven't yet seen the difference between integral
promotion
and arithmetic conversion.

--
Peter

Feb 21 '06 #39

P: n/a
On 2006-02-21, Peter Nilsson <ai***@acay.com.au> wrote:
Jordan Abel wrote:
On 2006-02-21, Peter Nilsson <ai***@acay.com.au> wrote:
> ... The integral promotion is only relevant to the left hand operand
> of shift expressions.
Then what could cause the left-hand operand (being, as established,
unsigned char) to be promoted to int at all? Is there some magical "all
types narrower than int get promed to int all the time no matter what"
rule i haven't heard about?


Not "no matter what", but generally they do get promoted as per
6.3.1.1p2.
The fact of 6.3.1.1p3 makes the integer promotion of the right hand
operand (of a shift operator) incidental.
It's not clear how

x {is unsigned short} <<= 1U

causes anything to be promoted to any signed type.


In cases where USHRT_MAX <= INT_MAX, we have...

x <<= 1u;
x = x << 1u;
x = ((int) x) << 1u;

...all being identical. The u suffix in 1u is irrelevant here, it's the
integral
promotion of x from unsigned short to int that may occur.


Why is anything being promoted to a type that is not the type of any
subexpression that is involved in the expression?

If, for the same premice, we instead have...

x += 1u;
x = x + 1u;

Then arithmetic conversion occurs on top of the integral promotion...

x = (unsigned) (int) x + 1u;

Whilst arithmetic conversion applies to binary +, it does not apply to
<<.

<snip>
> Because if USHRT_MAX <= INT_MAX, then you'll eventually be doing...
>
> x = (INT_MAX/2+1) << 1
I assume you mean

x = (unsigned short)(INT_MAX/2+1) << (unsigned short)1


Given the initial premice, they have the same semantics. Even the
explicit cast to (unsigned short) will not prevent integral promotion
from applying to the left operand.


But where is this "integral promotion" coming from. I thought that a
value in an expression could only be promoted to the type of another
value involved in the same expression - not some random type (int) found
elsewhere.
>> or even
>>
>> x <<= 1U; [it'll promote to unsigned int and safely drop back down]
>
> No, the two operands of shift operators are not subject to arithmetic
> promotion.


But your entire POINT rides on having it be promoted to signed int if
you use 1 instead of 1U or (unsigned short)1!


No. I think you haven't yet seen the difference between integral
promotion and arithmetic conversion.


Eh - It seems illogical, so I checked the standard [actually an
anonymous c89 draft, but close enough to the standard, doubt it's been
changed]

If an int can represent all values of the original type, the value is
converted to an int; otherwise it is converted to an unsigned int.
These are called the integral promotions.

Incidentally, UCHAR_MAX cannot be the same as INT_MAX, because int has a
sign bit, and unsigned char may not have padding bits.
Feb 21 '06 #40

P: n/a
John F wrote:
Try this:

unsigned char x = 0;
unsigned int y = INT_MAX; /*assuming less than MAX_INT bits*/

while( y )
{
x |= 1;
x <<= 1
}


How is that loop ever going to end
when nothing changes the value of y?

--
pete
Feb 21 '06 #41

P: n/a
Jordan Abel <ra*******@gmail.com> writes:
[...]
Incidentally, UCHAR_MAX cannot be the same as INT_MAX, because int has a
sign bit, and unsigned char may not have padding bits.


Suppose CHAR_BIT==16, UCHAR_MAX==65535, sizeof(int)==2 (32 bits), and
int has 15 padding bits. Exotic, but possible.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 22 '06 #42

P: n/a

"pete" wrote:
John F wrote:
Try this:

unsigned char x = 0;
unsigned int y = INT_MAX; /*assuming less than MAX_INT bits*/

while( y )
{
x |= 1;
x <<= 1
}


How is that loop ever going to end
when nothing changes the value of y?


thanks.... that's my pitfall of writing and not trying to lint it...

should decrement:

while( y-- ) ... of course...

thanks for correction.

regards
John
Feb 22 '06 #43

P: n/a
Jordan Abel wrote:
But where is this "integral promotion" coming from. I thought that a
value in an expression could only be promoted to the type of another
value involved in the same expression
- not some random type (int) found elsewhere.


new.c prints out "4" on my system.

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
char a = 0;

printf("\nsizeof (a + a) is %u\n", (unsigned)sizeof (a + a));
return 0;
}

/* END new.c */

--
pete
Feb 22 '06 #44

P: n/a
John F wrote:

"pete" wrote:
John F wrote:
Try this:

unsigned char x = 0;
unsigned int y = INT_MAX; /*assuming less than MAX_INT bits*/

while( y )
{
x |= 1;
x <<= 1
}


How is that loop ever going to end
when nothing changes the value of y?


thanks.... that's my pitfall of writing and not trying to lint it...

should decrement:

while( y-- ) ... of course...


Is your intention to iterate that loop
INT_MAX number of times?

I think this is more better:

unsigned char x = -1;
unsigned int y = 0;

while (x >>= 1) {
++y;
}

--
pete
Feb 22 '06 #45

P: n/a
Jordan Abel wrote:
On 2006-02-21, Peter Nilsson <ai***@acay.com.au> wrote:
Jordan Abel wrote:
It's not clear how

x {is unsigned short} <<= 1U

causes anything to be promoted to any signed type.
In cases where USHRT_MAX <= INT_MAX, we have...

x <<= 1u;
x = x << 1u;
x = ((int) x) << 1u;

...all being identical. The u suffix in 1u is irrelevant here, it's the
integral promotion of x from unsigned short to int that may occur.


Why is anything being promoted to a type that is not the type of any
subexpression that is involved in the expression?


You mean why does integral promotion exist? That's been covered
numerous times before in clc. But basically, int is supposed to be
the most efficient integer type in a C implementation.
But where is this "integral promotion" coming from. I thought that a
value in an expression could only be promoted to the type of another
value involved in the same expression
That's arithmetic conversion.
- not some random type (int) found elsewhere.
It's not random. Like I said, it has been covered before. [I'm just too
lazy
to find the references for you, but try comp.std.c. And it never _ever_
hurts to search for posts by Chris Torek. :-]
No. I think you haven't yet seen the difference between integral
promotion and arithmetic conversion.


Eh - It seems illogical, so I checked the standard [actually an
anonymous c89 draft, but close enough to the standard, doubt it's been
changed]


Integral promotion in C99 added extended integer types into the mix.
If an int can represent all values of the original type, the value is
converted to an int; otherwise it is converted to an unsigned int.
These are called the integral promotions.

Incidentally, UCHAR_MAX cannot be the same as INT_MAX, because int
has a sign bit, and unsigned char may not have padding bits.


If CHAR_BIT >= 15, there's nothing preventing int from being 2 bytes
and
having CHAR_BIT-1 padding bits. [Thus having 1 sign bit and CHAR_BIT
value bits, sufficient to store any value of an unsigned char.]

--
Peter

Feb 22 '06 #46

P: n/a

"pete" wrote:
John F wrote:

"pete" wrote:
> John F wrote:
>
>> Try this:
>>
>> unsigned char x = 0;
>> unsigned int y = INT_MAX; /*assuming less than MAX_INT bits*/
>>
>> while( y )
>> {
>> x |= 1;
>> x <<= 1
>> }
>
> How is that loop ever going to end
> when nothing changes the value of y?
thanks.... that's my pitfall of writing and not trying to lint it...

should decrement:

while( y-- ) ... of course...


Is your intention to iterate that loop
INT_MAX number of times?


How long does it take on a modern machine? Negligable for a single
execution. (Rationale see below.)
I think this is more better:

unsigned char x = -1;
Is propagation to 0xFFFF...FF garanteed? Thinking of other implementations
of signed values I'm not so sure. (signed bit, instead of two's
complement... with sign-bit not being affected by >> e.g. if this is still a
legal implementaion [1:12 am here... saturated with coffee and still too
tired to dig that standard up])
unsigned int y = 0;

while (x >>= 1) {
++y;
}


Would work on some machines. IIRC some preserve the sign on a shift right (I
hope this is still right...) ... thus this would loop forever.

John
Feb 22 '06 #47

P: n/a
John F wrote:

"pete" wrote:

I think this is more better:

unsigned char x = -1;


Is propagation to 0xFFFF...FF garanteed?


Yes.
N869
6.3.1.3 Signed and unsigned integers
[#1] When a value with integer type is converted to another
integer type other than _Bool, if the value can be
represented by the new type, it is unchanged.
[#2] Otherwise, if the new type is unsigned, the value is
converted by repeatedly adding or subtracting one more than
the maximum value that can be represented in the new type
until the value is in the range of the new type.

((-1) + (UCHAR_MAX + 1)) == UCHAR_MAX == 0xF...F
unsigned int y = 0;

while (x >>= 1) {
++y;
}


Would work on some machines.
IIRC some preserve the sign on a shift right (I
hope this is still right...) ... thus this would loop forever.


No.
The type of (x) is unsigned char.
It's value is positive after being initialized to -1,
and stays positive until it is decreased to zero,
at which time the loop ends.

--
pete
Feb 22 '06 #48

P: n/a

"pete" wrote:
John F wrote:

"pete" wrote:

> I think this is more better:
>
> unsigned char x = -1;


Is propagation to 0xFFFF...FF garanteed?


Yes.
N869
6.3.1.3 Signed and unsigned integers
[#1] When a value with integer type is converted to another
integer type other than _Bool, if the value can be
represented by the new type, it is unchanged.
[#2] Otherwise, if the new type is unsigned, the value is
converted by repeatedly adding or subtracting one more than
the maximum value that can be represented in the new type
until the value is in the range of the new type.

((-1) + (UCHAR_MAX + 1)) == UCHAR_MAX == 0xF...F


AH!!! Thanks!
> unsigned int y = 0;
>
> while (x >>= 1) {
> ++y;
> }


Would work on some machines.
IIRC some preserve the sign on a shift right (I
hope this is still right...) ... thus this would loop forever.


No.
The type of (x) is unsigned char.
It's value is positive after being initialized to -1,
and stays positive until it is decreased to zero,
at which time the loop ends.


I should go to sleep :-) Thanks.

unsigned int y=0;
unsigned char x=-1;
while( y++, x >> 1 );

does the job...

going to bed _now_ ...
John
Feb 22 '06 #49

P: n/a

In article <11********************@g43g2000cwa.googlegroups.c om>, "sl*******@yahoo.com" <sl*******@gmail.com> writes:
david ullua wrote:

In programming language like C, compiler may set CHAR_BIT predefined.
In the programming language that *is* C, the implementation *must*
define CHAR_BIT. It's not optional.
But I wonder whether there is some cases when we don't know the bit
size of a byte in hardware CPU, and should calculate it by programming
language.
To complicate matters, char is not required by the C standard to be the
machine "byte". It is only required to be at least 8 bits. And a
machine "byte" is not always 8 bits....


True. However:
So, given that it can't strictly be done in C


I don't think this is true. Consider that:

- integers must have a pure binary representation, which means
value bits are in order
- you can inspect the representation of any object using a
pointer to unsigned char

Given that, try this code:

#include <stdio.h>
int main(void)
{
unsigned i, c;
unsigned char *bp1, *bp2;

if (sizeof i > 1)
{
i = 0;
bp1 = bp2 = (unsigned char *)&i;
bp1++; /* point to second byte */
bp2 += sizeof i - 1; /* point to second-to-last byte */
for (c = 0; *bp1 == 0 && *bp2 == 0; c++)
i = 1u << c;
printf("bytes have %d bits in this implementation\n", (int)c - 1);
}
return 0;
}

This works for both big- and little-endian architectures, as far as I
can see, because it tests when the shift operator alters the second
or penultimate bytes. I don't offhand see a way for a conforming
implementation (where sizeof(unsigned) > 1) to produce the wrong
answer.

Extending the program to handle the case where sizeof(unsigned) is 1
is left as an exercise for the reader.

--
Michael Wojcik mi************@microfocus.com

"Well, we're not getting a girl," said Marilla, as if poisoning wells were
a purely feminine accomplishment and not to be dreaded in the case of a boy.
-- L. M. Montgomery, _Anne of Green Gables_
Feb 22 '06 #50

96 Replies

This discussion thread is closed

Replies have been disabled for this discussion.