ken@turtlevax.UUCP (Ken Turkowski) (02/28/85)
The VAX and PDP-11 have the property that
int x;
x = 12000;
write(df, &x, 2);
gives the same results whether an int is short or long.
On the 68000, this gives different results.
This could be interpreted as follows: truncation of bytes or words for
the DEC computers are appropriate for integers, whereas truncation for
the 68000 is appropriate for fractions. Taking the "first" digit of
12345 yields 5 for DEC, and 1 for Motorola.
I would like to be able to have the write sequence above give the same
results for the 68000, regardless of whether the int is long or short.
This would require the generation of a mask for the most significant
bit of an int, where the int could be any arbitrary size. Does the
following not work on any machine?
main() {
int x;
x = (-1) & ~((unsigned)(-1) >> 1);
printf("%x\n", x);
}
Then I could sequence through bits as follows:
for (i = 0; i < N; i++)
if (joe & (ms >> i))
printf("Bit %d of joe is set\n", i);
--
Ken Turkowski @ CADLINC, Menlo Park, CA
UUCP: {amd,decwrl,nsc,seismo,spar}!turtlevax!ken
ARPA: turtlevax!ken@DECWRL.ARPA
cottrell@NBS-VMS.ARPA (03/02/85)
/* > This would require generation of a mask for the most significant bit int msbit() { register int msb = 1; while ((msb <<= 1) > 0); return(msb); } I am assuming that the msb is used as the sign bit. If that's not portable, then shift until msb is zero, counting the shifts. Then return(1 << --count). (I am also assuming an int is more than one bit :-) jim */
ptw@encore.UUCP (P. Tucker Withington) (03/04/85)
>> This would require generation of a mask for the most significant bit
It should be easy to make a constant that masks a machine's "high" bit, but
as I mentioned a while back, ~(~(unsigned)0>>1) croaks pcc in a static
declaration; apparently because it does not know how to simplify casts in a
constant. (It works fine as auto or in an expression, but then you're doing
unnecessary work at run time, especially if you made it a #define.)
The only feedback I got was that you "should" be allowed to have casts in a
constant; that they were "accidentally" left out of K&R...
o.o --tucker
~
bass@dmsd.UUCP (John Bass) (03/08/85)
seems that this should work: #define MSB(a) (1<<((sizeof a) * 8 - 1)) for most unix machines. -- John Bass DMS Design (System Performance and Arch Consultants) {dual,fortune,idi,hpda}!dmsd!bass (408) 996-0557
MLY.G.SHADES%MIT-OZ@MIT-MC.ARPA (03/08/85)
~(~(unsigned)0>>1) is not portable either i believe. as i remember in k&r the >> operator can, and in some compilers does, allow sign propagation. this is nominally a bug in the interpretation of unsigned arithmetic but that is the way of life here in the big city. i can't think of any way to guarantee a compiler time, compiler generated, constant for the most significant bit that is going to work on some of the more brain-damaged c compiler's around. shades%mit-oz@mit-mc.arpa
stew@harvard.ARPA (Stew Rubenstein) (03/10/85)
> seems that this should work: > > #define MSB(a) (1<<((sizeof a) * 8 - 1)) > > for most unix machines. > -- > John Bass > DMS Design (System Performance and Arch Consultants) > {dual,fortune,idi,hpda}!dmsd!bass (408) 996-0557 Is it portable to assume 8 bit bytes? Answer: no, but since there is no bitsizeof operator, sometimes we must. There are unix machines which do not use 8 bit bytes (the BBN C-30 and C-70 come to mind, maybe also some honeywell machines). There is also the PDP-10 which, to the best of my knowledge, does not run unix, but does have C. -- ----------------------- Stew Rubenstein UUCP: ihnp4!harvard!stew Harvard Chemistry ARPA: stew@harvard
dae@psuvax1.UUCP (Daemon) (03/11/85)
The below is at least a stab in the right direction;
our cpp is the "old" 4.2 one--the one without the -M
option.
-----------------------cut here for msb.c------------------------------
#define msb(x) (1 << (8 * sizeof(x)) - 1)
main()
{
int i = msb(int);
short s = msb(short);
char c = msb(char);
printf("Int: %d\n", i);
printf("Short: %d\n", s);
printf("Char: %d\n", c);
}
--------------------------end msb.c-----------------------------------
--
\ / \/ From the furnace of Daemon ( ...{psuvax1,gondor,shire}!dae )
\ / +1 814 237 1901 "I will have no covenants but proximities" [Emerson]
\/
Don't get mad. Get even.
mab@druxp.UUCP (BlandMA) (03/12/85)
John Bass in article <169@dmsd.UUCP> recommends: > #define MSB(a) (1<<((sizeof a) * 8 - 1)) Stew Rubenstein in article <455@harvard.ARPA> replies: > Is it portable to assume 8 bit bytes? Answer: no.... If you're running UNIX System V (and possibly other UNIX systems, I don't know), take a look at /usr/include/values.h, which defines a number of constants that might be of use, such as: BITSPERBYTE number of bits in a byte HIBITS bit mask for the high bit of a short HIBITI ditto for int HIBITL ditto for long MAXSHORT maximum value of a signed short MAXINT ditto for int MAXLONG ditto for long HIBITS, HIBITI, and HIBITL are macros defined in terms of BITSPERBYTE using the same formula that John Bass gave. BITSPERBYTE is conditionally compiled using #if. UNIX is a trademark of AT&T Bell Laboratories. -- Alan Bland {ihnp4, allegra}!druxp!mab AT&T Information Systems Labs, Denver
dave@inset.UUCP (Dave Lukes) (03/20/85)
Newsgroups: net.lang.c Subject: Re: How does one construct a mask for the MS bit? References: <8849@brl-tgr.ARPA>, <169@dmsd.UUCP> > seems that this should work: > > #define MSB(a) (1<<((sizeof a) * 8 - 1)) > > for most un*x machines. > -- > John Bass MOST UN*X machines?? Go suck a Honeywell !! (or A BBN) ==== ``Well, it works on all the machines I use'' is a great attitude if you can afford it: not everyone can (or wants to!). Even if you are willing to have your code break on a machine with one more bit, at least COMMENT the fact beforehand. ======= Also, if the the byte/word/long ... size is so important: WORK IT OUT !!!!!!!!!! ========================== How's this: bitsperword() { unsigned int i = ~0; int nbits = 0; do nbits++; while((i >>= 1) != 0); return nbits; } Yours portably, Dave Lukes