439,993 Members | 1,947 Online
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
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 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" 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, 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" 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 themachine "byte". It is only required to be at least 8 bits. And amachine "byte" is not always 8 bits. And some ancient beasts evenenables the programmer to specify how many bits are in a byte. So onthose machines (I believe Unisys was one) you "defined" how many bitswas 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" wrote: Hi, Rod,Martin and Vladimir has given a shorten method to find bit size of abyte in c :). I think maybe Joe was not intended get an answer ofcalculation, 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 bitsize of a byte in hardware CPU, and should calculate it by programminglanguage. The case's just like kidding, since we don't know bits ofCPU, 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 wrote: On 21 Feb 2006 01:02:30 -0800, "david ullua" wrote:Hi, Rod,Martin and Vladimir has given a shorten method to find bit size of abyte in c :). I think maybe Joe was not intended get an answer ofcalculation, 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 bitsize of a byte in hardware CPU, and should calculate it by programminglanguage. The case's just like kidding, since we don't know bits ofCPU, 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 wrote: On 2006-02-21, Al Balmer wrote: On 21 Feb 2006 01:02:30 -0800, "david ullua" wrote:Hi, Rod,Martin and Vladimir has given a shorten method to find bit size of abyte in c :). I think maybe Joe was not intended get an answer ofcalculation, 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 bitsize of a byte in hardware CPU, and should calculate it by programminglanguage. The case's just like kidding, since we don't know bits ofCPU, 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 wrote: On 2006-02-21, Richard G. Riley wrote: On 2006-02-21, Al Balmer wrote: On 21 Feb 2006 01:02:30 -0800, "david ullua" wrote:Hi, Rod,Martin and Vladimir has given a shorten method to find bit size of abyte in c :). I think maybe Joe was not intended get an answer ofcalculation, 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 bitsize of a byte in hardware CPU, and should calculate it by programminglanguage. The case's just like kidding, since we don't know bits ofCPU, 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" 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 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: Also see Feb 21 '06 #18

 P: n/a CBFalconer wrote: "Richard G. Riley" wrote: On 2006-02-21, Al Balmer 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" 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" writes: On 2006-02-21, Jordan Abel wrote: On 2006-02-21, Richard G. Riley wrote: On 2006-02-21, Al Balmer 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 #include 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 San Diego Supercomputer Center <*> 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" 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 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 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" 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 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" 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 wrote: Jordan Abel wrote: On 2006-02-21, pete 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 wrote: Jordan Abel wrote: On 2006-02-21, pete 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 wrote: Jordan Abel wrote: On 2006-02-21, pete wrote: > Jordan Abel wrote: >> On 2006-02-21, pete 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" writes: "david ullua" 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" wrote in message news:11**********************@z14g2000cwz.googlegr oups.com... stathis gotsis wrote: "sl*******@yahoo.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 Jordan Abel wrote: On 2006-02-21, Peter Nilsson 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 <<. 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 wrote: Jordan Abel wrote: On 2006-02-21, Peter Nilsson 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 <<. > 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 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 San Diego Supercomputer Center <*> 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 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 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" 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 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.