Fog Creek Software
Discussion Board




Confused by K&R bitwise section...

I was lopping along merrrily, until they got to this paragraph explaining the portability of a bitwise operator.  After reaching that paragraph, my understanding came to a  screeching halt.

Here's the example from the book...

First they explain how ~ yeilds the complement of an integer like this (example from the book):

x = x & ~077 sets the last 6 bits of x to zero. 

OK, at first I thought this was wrong because 077 in binary form is 1001101.    However if you assume that each number in 077 is represented individually in binary form, you could say that 077 = 0 111 111 ( 0 7 7 ).

So I went with that assumption...until I got to this.

K&R explains that the above use is more portable than using this(also straight from the book):

x = x & 0177700.

According to K&R, the reason this is more portable is because the integer constant (0177700) assumes that x is 16 bit. 

And this is where I get confused. 

(1)Assuming that the point of the bitwise & is to set the last 6 bits of x to zero, how is there an assumption being made about whether x is 16 bits or not? 

(2)Also, I don't see how "x & 0177700" sets the last 6 bits of x to 0 under any scenario. 

(3)And I don't get how this solution is *less* portable than the other.


Aside rant:  It's these sort of subtle logical disconnects that often discourage people from learning material fully.  Rant off. :)

Thanks!

Confused

Confused
Thursday, June 10, 2004

Numbers with leading 0's are octal.

Yet another anon
Thursday, June 10, 2004

Endianess may come into play here.  Not sure if that's what is meant.

christopher baus (www.baus.net)
Thursday, June 10, 2004

"yet another anon":

Problem solved.

I never use octal integer constants and when I do run across octals, it's always as an escaped character constant.  My brain just didn't register this.

Now I (rightly) feel like an idiot.  Thank you for your help.

-no longer Confused

Confused
Thursday, June 10, 2004

You shouldn't feel like an idiot - it's an inconsistency in language design which should never have been enforced as standard.

No C
Thursday, June 10, 2004

You should be proud that you didn't know octal. It's a silly system anyway.

E.g. what is 0377? ooh, a full byte...

Alex
Thursday, June 10, 2004

Some old DEC hardware, and maybe others, had 36 bit words.  36 bit words make 9 bit bytes convenient and octal constants very useful.

Doug
Thursday, June 10, 2004

"It's a silly system anyway."

Well, that depends on context. It was commonly used on systems that had bitwidths that were multiples of 3 - e.g. the 36 bit wide DEC-10 series.

That said, I never understood why it was so prevalent in PDP-11 contexts, because they were 16 bits wide.

sgf
Thursday, June 10, 2004

It's Octal.

Why K&R weren't content with just hex and decimal I have no idea...

Matt
Thursday, June 10, 2004

Unfortunately, 'C' is full of these little gotchas.  Why should a literal number be octal because it starts with a leading zero '0'?  (Unless it's a Zero-X "0x...", because THAT's a hex number)

Well, it just is.  Even if you only use decimal and hexadecimal to stay away from this gotcha, somebody else will have it in an example, so you HAVE to know it's there.

Plus, the Unix file system permissions are done in 3 bits each, so this fits into octal numbers really well, so that's what people use for that.

And can we do binary numbers the same way?  I don't think so...

AllanL5
Thursday, June 10, 2004

In the old days (1960-1970) many computers used 6 bit characters not the 8 bit codes we use today.  Octal was a convienent way to express the binary codes then. As machines moved to 8 bit characters (Ascii and Ebcdic) from the 6 bit BCD codes hex became the standard way to represent the internal binary codes.

As to the question 077 = 63 decimal and 111111 binary. ~077 would be 0177700 for 16 bits.

I am not sure about this but I assume that in evaluating x &~077 the compiler will adjust  ~-077 to match the length of x. If this is the it is better to use ~077 instead of 0177700 which would not adjust. 

John
Thursday, June 10, 2004

A common gotcha is to have a list of constants and you
neatly format them with leading 0s to line up nicely.

Martin Beckett
Thursday, June 10, 2004

This gets even more horrid in JScript.  I made every use of octal literals a compiler warning in JScript .NET.  Details on just how horrid it is here:

http://blogs.msdn.com/ericlippert/archive/2003/10/23/53278.aspx

Eric Lippert
Thursday, June 10, 2004

Octal codes make sense in some circumstances.
A lot of instruction sets make sense in octal.
Both the 6502 & the 8080/Z80 instruction sets (as does the PDP set) make sense in Octal. IIRC most of instructions were all of the form (in binary)
xxyyyzzz
where for the mov instruction
and yyy & zzz are from this table
000=B register
001=C register
010=D register
011=E register
100=H register
101=L register
110=(HL) access memory pointed to by HL pair
111=A register (aka accumulator)
various other opcodes were similar
so
xx=00 zzz=100 is increment
xx=00 zzz=101 dec
xx=00 zzz=110 load register with constant byte
xx=10 yyy=000 add register zzz to accumulator
xx=10 yyy=001 add register zzz to accumulator with carry
xx=10 yyy=002 sub register zzz from accumulator
xx=10 yyy=003 sub register zzz to accumulator with carry
xx=10 yyy=004 and register zzz to accumulator
xx=10 yyy=005 xor register zzz to accumulator
xx=10 yyy=006 or register zzz to accumulator
xx=10 yyy=007 compare register zzz to accumulator

Those are the easy ones I can pull out of a Z80 instruction set I found online.
I seem to remember that the same rules apply to the jump absolute, jump relative and call instructions but with seven values being assigned to the various flags.

The same tricks work for the 8086 as well.

Peter Ibbotson
Friday, June 11, 2004

*  Recent Topics

*  Fog Creek Home