On the Gould UTX compiler, the default is to treat chars not explicitly
declared unsigned as signed. This is so that anything that you might
port over from a PDP-11 will work (apparently it made porting of some things
easier when UN*X was originally ported to these machines). However, there
is a compiler option that will make all chars unsigned, so if you're porting
something from a VAX, you can have it that way too. (Actually, the most
efficient mode is the all-unsigned mode, so the sense of the option should
probably be reversed.) Incidentally, I am one of those cretins that
sometimes uses "unsigned char" instead of "unsigned short"; I have an
application where I save over 2M of memory by doing that. I have never
found a use for signed chars.
---
It's been said by many a wise philosopher that when you die and your soul
goes to its final resting place, it has to make a connection in Atlanta.
Dave Cornutt, Gould Computer Systems, Ft. Lauderdale, FL
UUCP: ...{sun,pur-ee,brl-bmd}!gould!dcornutt
or ...!ucf-cs!novavax!houligan!dcornutt
ARPA: wait a minute, I've almost got it...
"The opinions expressed herein are not necessarily those of my employer,
not necessarily mine, and probably not necessary."
If you're porting something from a VAX, you're in for one hell of a surprise
if you turn on the "make chars unsigned by default" option; the UNIX C
compiler for the VAX (and probably the VMS compiler as well) treats "char"
as a request for a signed character.
> I have never found a use for signed chars.
V6 UNIX did; the "p_pri" field in the "proc" structure held the process
priority, and the range of priorities included both positive and negative
values. Since V7 was ported to an Interdata machine, whose compiler treated
"char" as a request for an unsigned character, an bias PZERO was added so
that the range of priorities started at 0.
Note, however, that this was a use for signed "char"s, NOT for signed
characters. Unfortunately, C conflates the notion of "character" and "very
small integer" into one type, namely "char".
--
Guy Harris
{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
g...@sun.com (or g...@sun.arpa)
- Mitch Bayersdorfer
Applied Technology Organization
Artificial Intelligence Laboratory
Floor 4, Building 23, Kodak Park
Rochester, NY 14650
(716) 477-1792
...!rochester!kodak!bayers
Some machines have fast function calls and assembler instructions for
directly addressing bits. But if you want portable, how about this?
It should run on any C with an appropriate setting of the first define.
Make sure that the _BPW_ is 36 or 16 or however many bits there are in
an (int) on your machine. Make sure you use (int) and not (long) or (char)
for the array; on many machines accessing a (char) is a lot more work than
accessing an (int).
#define _BPW_ (36) /* bits per word (natural machine size, not char) */
#define _BIT_(bit) (1<<((bit)%_BPW_)) /* internal use */
#define _WORD_(name,bit) ((name)[(bit)/_BPW_]) /* internal use */
#define DECLARE(name,bits) int name[1+((bits)/_BPW_)]
#define SET(name,bit) (_WORD_(name,bit)|=_BIT_(bit))
#define CLEAR(name,bit) (_WORD_(name,bit)&=~_BIT_(bit))
#define FLIP(name,bit) (_WORD_(name,bit)^=_BIT_(bit))
#define TEST(name,bit) ((_WORD_(name,bit)&_BIT_(bit))!=0)
#define SAME(name1,name2,bit) \
(((_WORD_(name1,bit)^_WORD_(name2,bit))&_BIT_(bit))==0)
etc.
The immediate (and naive) approach is to say:
struct{
bit:1
}[LOTS]
However, C does not support bit fields directly. For every bit
field it will allocate a full word. This is distressing particularly
if you have a sparse structure, and many of them.
A better approach is to define a subroutine or macro as
following:
#define getbit(x,p) ((x >> p)&~(~0 << 1))
This is from K&R (God bless 'em). A "setbit" macro could be
fudged up fairly similiarly. Of course for this to work *really*
good, you should make sure that the struct uses char's ,not int's --
vaxes have a (literally) twisted concept of how bytes fit into ints.
By using chars you avoid the little/big -endian problems. Also, you'll
probably want (somewhere) a #define for the number of bits in a
character (just to cover all bases) for computational purposes.
The structure I used look like this:
unsigned char bitmap[1024][1024]
and used the previous macro as a sub-routine to reference bits within
the char's. I set bits by simple multiplications.
tp.
--
----------------------------------------------------------
- ARPA: Brisco@rutgers -
- UUCP: (ihnp4!ut-sally, allegra!packard) !caip!brisco -
----------------------------------------------------------