[comp.lang.c] binary constants

jfriedl@frf.omron.co.jp (Jfriedl) (11/17/89)

There's one (particular) hassle I've always had when programming
in C and I thought I'd ask about it.....

In some cases, I find it would be much more natural to represent
integral constants in binary, but I don't know of an easy way to
do this. For example, I find the mythical: (can you pretend these
are binary constants? Sure, I knew you could):
	#define FLAG_A		00000001000
	#define FLAG_B		00000010000
	#define FLAG_C		00000100000
	#define FLAG_D		00001000000
	#define FLAG_E		00010000000
	#define FLAG_F		00100000000
	#define FLAG_MASK	00111111000
rather more immediately obvious than
	#define FLAG_A		0x0008
	#define FLAG_B		0x0010
	#define FLAG_C		0x0020
	#define FLAG_D		0x0040
	#define FLAG_E		0x0080
	#define FLAG_F		0x0100
	#define FLAG_MASK	0x01F8
This example may be contrived, but the idea is there. Not only
does it indicate the desired value, but also that this data is
inherently binary and, if applicable to the situation, the
"width" of the data.

So, I have this retched macro that seems to work for short
binary constants:
    #define B(N)                             (	\
        ((1==(((2 ## N)         )%10))   ) |	\
        ((1==(((2 ## N)/10      )%10))<<1) |	\
        ((1==(((2 ## N)/100     )%10))<<2) |	\
        ((1==(((2 ## N)/1000    )%10))<<3) |	\
        ((1==(((2 ## N)/10000   )%10))<<4) |	\
        ((1==(((2 ## N)/100000  )%10))<<5) |	\
        ((1==(((2 ## N)/1000000 )%10))<<6) |	\
        ((1==(((2 ## N)/10000000)%10))<<7)   )
(non-ANSI compilers might try "/**/" rather than " ## ").

This has worked well for an 88K disassembler that I wrote,
where I dealt a lot in instruction opcode fields, etc.
For example, the following is pulled verbatim from it:
			.
			.
			.
	IMM16   = extract(16, bits of, inst, starting at bit,  0),
	S1	= extract( 5, bits of, inst, starting at bit, 16),
	D	= extract( 5, bits of, inst, starting at bit, 21),
	which	= extract( 6, bits of, inst, starting at bit, 26);

	/* first, just get the name of this instruction */
	switch((int)which)
	{
	    default:
		return(-1);

	    case B(000000):  name = "xmem.bu";	break;
	    case B(000001):  name = "xmem";	break;
	    case B(000010):  name = "ld.hu";	break;
			.
			.
			.
To anyone familiar with the mc88100, and looking at the
appropriate spot in the manual (as indicated nearby in
the program), this is *wonderfully* clear.

ANYWAY, finally to my questions:
    Is there a way better than the above macro to do this?
    I've gcc v1.36 -- does it have any special stuff for this?
    Any comments (other than "Ack!Gag!Barf!") about the above macro?

I'll summarize if there seems to be enough interest...

	*jeff*
-----------------------------------------------------------------------------
Jeffrey Eric Francis Friedl                    jfriedl@nff.ncl.omron.co.junet
Omron Tateisi Electronics, Dept. OE                         Nagaokakyo, Japan
Fax: 011-81-75-955-2442                        Phone: 011-81-75-951-5111 x154
direct path from UUNET:                             ...!uunet!othello!jfriedl

tps@chem.ucsd.edu (Tom Stockfisch) (11/19/89)

In article <305@frf.omron.co.jp> jfriedl@frf.omron.co.jp (Jfriedl) writes:

>In some cases, I find it would be much more natural to represent
>integral constants in binary, ...
>	#define FLAG_A		00000001000
>	#define FLAG_B		00000010000
>	#define FLAG_C		00000100000
>	#define FLAG_D		00001000000
>	#define FLAG_E		00010000000
>	#define FLAG_F		00100000000
>	#define FLAG_MASK	00111111000
>rather more immediately obvious than
>	#define FLAG_A		0x0008
>	...

Here are different ways I have done it:

(1) Brute Force (useful only for a small range, like 0-15)

	/* base2.h */
	# define B0000	0
	# define B0001	1
	...
	# define B1111	15

(2) Portable Macro (lots of typing required)

	# define B8(a,b,c,d,e,f,g,h)  (				\
		((((((((((((a) << 1) | (b) ) << 1 ) | (c) )     \
		<< 1 ) | (d) << 1 ) | (e) << 1 ) | (f) )	\
		<< 1 ) | (g) ) << 1 ) | (h)			\
	)
	...
	x &=	B8(1,1,1,1,1,1,1,1);	/* mask off lower 8 bits */
	# define FLAG_MASK2	B8( 0,0,1,1,1,1,1,1,0,0 )

(3) Name That Bit (useful for one bit set)

	# define 
	# define FLAG_A		(1<<3)
	# define FLAG_B		(1<<4)
	...

	or

	# define Bit(b)	(1 << (b))
	...
	# define FLAG_A		Bit(3)
	# define FLAG_B		Bit(4)
	...

(4) C Idiom
	
	Memorize the bit patterns of 0x0 thru 0xf and then write your
	constants as, e.g.
		
		x &=	0xf;	/* mask lower nybble */
		# define FLAG_MASK	0x1f8
	
	If the bit pattern is really more lucid than the hex representation,
	add a comment:
		
		# define MASK	0x41416   /* bin 100 0001 0100 0001 0110 */



For constants with 1 bit set I tend to use (3), and for the rest I just use
(4).
-- 

|| Tom Stockfisch, UCSD Chemistry	tps@chem.ucsd.edu

raymond@math.berkeley.edu (Raymond Chen) (11/19/89)

/* Disgusting macro alert! */

#define BIT1(x) (0 x
#define BIT2(x) ((0 x
#define BIT3(x) (((0 x
/*  ...  */
#define BIT6(x) ((((((0 x

#define O *2)
#define I *2 + 1)

main()
{
printf("%x",  BIT6(I O I O I O));   /* the 6-bit number 101010 */
}

----- alternately -----

#define OOOO *16)
#define OOOI *16+1)
#define OOIO *16+2)
/* ... */
#define IIII *16+15)

#define BIT4(x) (0 x
#define BIT8(x) ((0 x
/* ... */
#define BIT16(x) ((((0 x

main()
{
printf("%x", BIT16(OOOO OIOI IOIO OIIO)); /* the 16-bit number
						0000 0101 1010 0110 */
}

/* Disclaimer:  I don't use this!  I just wrote it to see if it 
		could be done.  It would be curious to compare this
		against the original poster's macro which
		approaches the problem from a different angle. 
*/

Raymond Chen (mathematician by training, hacker by choice)
			raymond@math.berkeley.edu

chris@mimsy.umd.edu (Chris Torek) (11/20/89)

One of my favourite silly ideas for C is now ruled out by X3J11's
`#' `stringize' preprocessing operator (or at least, would require
some other syntax), but it went like this:  Instead of having hex,
decimal, octal, binary, etc., constant syntaxes, why not have a
single syntax for `based numbers'?  The initial radix would always
be decimal; the format would be something like

	#(base,expr)

Numbers in the `expr' part would be interpreted in the base given by
the `base' expression.  Any value from 2 to 36 would be legal for the
base.  All `numbers' would be of the form

	[0-9][0-9a-zA-Z]*

where ordinary digits represent themselves and letters represent digits
>= 10 in the obvious manner.  (Whether digits greater than the base
would be legal is essentially irrelevant.)

The sneaky (or silly) bit is that both `base' and `expr' would be
arbitrary constant expressions.  This would be useful for obfuscation
such as

	#(3+#(2,#(6,13)-0010),#(5,11)/30)

which is actually 1.

(I think.)

Whether the base is always decimal is an unresolved question.  (Bases
that are part of the base-forming expression are definitely decimal,
but bases that are part of the based-expression---the stuff to the
right of the comma---might start in the base determined by the thing
to the left.  This would probably be a bad idea, since macro expansion
would yeild unpredictable results if the base part were multi-digit.
Of course, this would be even better for obfuscatory purposes.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

bright@Data-IO.COM (Walter Bright) (11/21/89)

In article <305@frf.omron.co.jp> jfriedl@frf.omron.co.jp (Jfriedl) writes:
<In some cases, I find it would be much more natural to represent
<integral constants in binary.

I agree (as I create bit patterns for icons for graphics). In fact,
Datalight C and Zortech C/C++ have always supported binary constants:

	int x = 0x16;		/* 22	*/
	int o = 026;		/* 22	*/
	int b = 0b10110;	/* 22	*/

printf() and scanf() support it also (with the %b format specifier).
If you have the source to gcc, I suspect that the modifications to the
lexical analyzer are trivial.

P.S. ANSI C rejected my suggestion for this! Even though there is 'prior art'.

peter@ficc.uu.net (Peter da Silva) (11/21/89)

For most cases binary constants are just fine in HEX. But for image data
it's a real pain. I'd really love to be able to do this:

struct sprite smileyface = {
	0, 0, 32, 11,
	{ 0b0000000000000000,
	  0b0000111111110000,
	  0b0011000000001100,
	  0b0100011001100010,
	  0b0100000000000010,
	  0b0101110000111010,
	  0b0100100000010010,
	  0b0100011111100010,
	  0b0011000000001100,
	  0b0000111111110000,
	  0b0000000000000000
	}
};
-- 
`-_-' Peter da Silva <peter@ficc.uu.net> <peter@sugar.lonestar.org>.
 'U`  --------------  +1 713 274 5180.
"ERROR:  trust not in UUCP routing tables"
	-- MAILER-DAEMON@mcsun.EU.net

tneff@bfmny0.UU.NET (Tom Neff) (11/21/89)

Remember that for many purposes, you can use octal "bits" instead of
true binary.  Only when bit space is crucial does it matter.

I agree 0bNNNNN would have been nice, however, and I sure wish X3J11
had taken time off from rabbinical hairsplitting to add it.  Ah well.
-- 
'We have luck only with women -- not spacecraft!'     \\  Tom Neff
 -- R. Kremnev, builder of failed Soviet FOBOS probes //  tneff@bfmny0.UU.NET

ok@mudla.cs.mu.OZ.AU (Richard O'Keefe) (11/21/89)

In article <7065@ficc.uu.net>, peter@ficc.uu.net (Peter da Silva) writes:
> For most cases binary constants are just fine in HEX. But for image data
> it's a real pain.

Who said everything the C compiler sees had to be written by hand?
If you need binary numbers, use m4.  It's a UNIX utility, and there is
a public domain version by Ozan Yigit.

Here's all you need for binary numbers, and you don't really
need rhead and rtail as separate macros:

define(rhead,`substr($1,decr(len($1)),1)')dnl
define(rtail,`substr($1,0,decr(len($1)))')dnl
define(bin,`ifelse($1,,0,`eval(bin(rtail($1))*2+rhead($1))')')dnl

With the aid of this, Peter da Silva would just write
    struct sprite smileyface =
	{
	    0, 0, 32, 011,
	    {
		bin(0000000000000000),
		bin(0000111111110000),
		bin(0011000000001100),
		bin(0100011001100010),
		bin(0100000000000010),
		bin(0101110000111010),
		bin(0100100000010010),
		bin(0100011111100010),
		bin(0011000000001100),
		bin(0000111111110000),
		bin(0000000000000000),
	    }
	};

If we change the definition of bin to
define(bin,`ifelse($1,,0,`eval(bin(rtail($1))*2+
	    ifelse(rhead($1),0,0,rhead($1),_,0,1))')')dnl

the bit map could be either as shown above OR as shown below

		bin(________________),
		bin(____@@@@@@@@____),
		bin(__@@________@@__),
		bin(_@___@@__@@___@_),
		bin(_@____________@_),
		bin(_@_@@@____@@@_@_),
		bin(_@__@______@__@_),
		bin(_@___@@@@@@___@_),
		bin(__@@________@@__),
		bin(____@@@@@@@@____),
		bin(________________),

I find this version clearer still.  (By the way, it took 20 minutes to
knock this together, I'm rather rusty with M4.)

diamond@csl.sony.co.jp (Norman Diamond) (11/21/89)

In article <20830@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:

>One of my favourite silly ideas for C is now ruled out by X3J11's
>`#' `stringize' preprocessing operator (or at least, would require
>some other syntax), but it went like this:  Instead of having hex,
>decimal, octal, binary, etc., constant syntaxes, why not have a
>single syntax for `based numbers'?  The initial radix would always
>be decimal; the format would be something like
>	#(base,expr)
>Numbers in the `expr' part would be interpreted in the base given by
>the `base' expression.  Any value from 2 to 36 would be legal for the
>base.  All `numbers' would be of the form
>	[0-9][0-9a-zA-Z]*

The ISO Extended Pascal standard has numbers almost exactly like this.
The syntax is base#expr, expr is of the form [0-9a-zA-Z][0-9a-zA-Z]*,
and any value from 2 to 36 is legal for the base.  "expr" must be a
constant though, not really an expr.  (base must be a constant too.)

This could be added as an extension to C, except that if "expr" happens
to match a formal parameter name in a macro expansion then the expr
must be stringized instead.  Alternatively, Mr. Torek's syntax could
always be accepted as an extension, because #( is never legal in X3J11.
(The processor would have to give a warning before accepting it.
I think.)

-- 
Norman Diamond, Sony Corp. (diamond%ws.sony.junet@uunet.uu.net seems to work)
  Should the preceding opinions be caught or     |  James Bond asked his
  killed, the sender will disavow all knowledge  |  ATT rep for a source
  of their activities or whereabouts.            |  licence to "kill".

mlandau@bbn.com (Matt Landau) (11/22/89)

On the subject of binary constants for creating cursor or image data,
here's a reposting of one of the more clever things I've seen come 
across comp.lang.c.  It's trivial to adapt this to use a syntax more
suited to traditional sets of flags, etc.

--
 Matt Landau			Oblivion gallops closer,
 mlandau@bbn.com		    favoring the spur, sparing the rein.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Article 5640 of comp.lang.c:
>From: ado@elsie.UUCP (Arthur David Olson)
Newsgroups: comp.lang.c,comp.lang.c++
Subject: Re: Binary integer literals
Date: 12 Dec 87 01:15:32 GMT

#include <stdio.h>

#define __	((((((((((((((((0
#define _	<<1|0)
#define X	<<1|1)

static unsigned short CursorPattern[16] = { 
	__	X X X X X X X X _ _ _ _ _ _ _ _ 	,
	__	X _ _ _ _ _ X _ _ _ _ _ _ _ _ _ 	,
	__	X _ _ _ _ X _ _ _ _ _ _ _ _ _ _ 	,
	__	X _ _ _ _ _ X _ _ _ _ _ _ _ _ _ 	,
	__	X _ _ _ _ _ _ X _ _ _ _ _ _ _ _ 	,
	__	X _ X _ _ _ _ _ X _ _ _ _ _ _ _ 	,
	__	X X _ X _ _ _ _ _ X _ _ _ _ _ _ 	,
	__	X _ _ _ X _ _ _ X _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ X _ X _ _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ _ X _ _ _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 	,
	__	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
};

main()
{
	int	i;

	for (i = 0; i < sizeof CursorPattern / sizeof CursorPattern[0]; ++i)
		(void) printf("%04x\n", CursorPattern[i]);
	return 0;
}

clive@ixi.co.uk (Clive Feather) (11/22/89)

[I finally get to follow up to Chris Torek]
In article <20830@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>One of my favourite silly ideas for C is now ruled out by X3J11's
>`#' `stringize' preprocessing operator (or at least, would require
>some other syntax), but it went like this:  Instead of having hex,
>decimal, octal, binary, etc., constant syntaxes, why not have a
>single syntax for `based numbers'?  The initial radix would always
>be decimal; the format would be something like
>	#(base,expr)
>Numbers in the `expr' part would be interpreted in the base given by
>the `base' expression.  Any value from 2 to 36 would be legal for the
>base.  All `numbers' would be of the form
>	[0-9][0-9a-zA-Z]*
>where ordinary digits represent themselves and letters represent digits
>>= 10 in the obvious manner.  (Whether digits greater than the base
>would be legal is essentially irrelevant.)

Algol 68 (yes, some of us once used it) uses the following notation for bit
patterns:

    2r11001000  == 200
    4r3020      == 200
    8r310       == 200
    16rc8       == 200

This could be trivially extended to any base up to 36. It has advantages over
Chris's notation, in that the numbers are already pp-numbers (see the
discussion in comp.std.c), and it doesn't use a new operator.

>The sneaky (or silly) bit is that both `base' and `expr' would be
>arbitrary constant expressions.  This would be useful for obfuscation
>such as
>	   #(3+#(2,#(6,13)-0010),#(5,11)/30)
>which is actually 1.
>(I think.)
You're right - silly is the word :-).


-- 
Clive D.W. Feather
IXI Limited
clive@ixi.uucp
...!uunet!ukc!ixi!clive (riskier)

scjones@sdrc.UUCP (Larry Jones) (11/24/89)

In article <14941@bfmny0.UU.NET>, tneff@bfmny0.UU.NET (Tom Neff) writes:
> I agree 0bNNNNN would have been nice, however, and I sure wish X3J11
> had taken time off from rabbinical hairsplitting to add it.  Ah well.

For the Nth time, X3J11 received hundreds, if not thousands, of
suggestions for nice little enhancements, none of which was
clearly superior to any other.  How were we to choose which to
add and which to leave out?  If we had adopted them all, C would
be bloated beyond recognition!  Our decision was to forget about
things that would be "nice" and concentrate instead on things
that were needed.
----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@SDRC.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"You know how Einstein got bad grades as a kid?  Well MINE are even WORSE!"
-Calvin

chris@mimsy.umd.edu (Chris Torek) (11/29/89)

In article <20830@mimsy.umd.edu> I wrote:
>... This would be useful for obfuscation such as
>	#(3+#(2,#(6,13)-0010),#(5,11)/30)
>which is actually 1.  (I think.)

Too much obfuscation; it comes out to 0.2, which truncates (integer
arithmetic) to 0.  That should have been #(5,110) in there.

Anyway, while specific syntaxes for specific bases (8 and 16, and
perhaps 0b for 2 as well, in addition to the `plain' base 10) are
all well and good, it is often better to get rid of specifics and
move toward abstracts.  Those of you who are trying to design `D'
(or `P') might consider dumping 0-octal and 0x-hex in favour of
something sane, like <base>r<text>, 2r11001 = 8r31 = 25 = 16r19.
Or for the mathematically TeXish, perhaps <text>_<base>: 11001_2 =
31_8 = 25 = 19_16 = 0p_36.  (Of course in TeX one has to write
19_{16}....)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

poser@csli.Stanford.EDU (Bill Poser) (11/29/89)

In article <20989@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>Those of you who are trying to design `D'
>(or `P') might consider dumping 0-octal and 0x-hex in favour of
>something sane, like <base>r<text>, 2r11001 = 8r31 = 25 = 16r19.

Isn't this the approach taken in Algol-68? I'm curious if experience
with Algol sheds any light on whether it is a good idea. It seems
attractive to me.

I've recently been reading up on Algol-68 and am constantly struck by
how many features of more recent languages are to be found there.
I'm not sure that its a good idea to have so many different things
in one language, but the designers sure thought of a lot of interesting
things.

henry@utzoo.uucp (Henry Spencer) (11/30/89)

In article <20989@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>Anyway, while specific syntaxes for specific bases (8 and 16, and
>perhaps 0b for 2 as well, in addition to the `plain' base 10) are
>all well and good, it is often better to get rid of specifics and
>move toward abstracts.  Those of you who are trying to design `D'
>(or `P') might consider dumping 0-octal and 0x-hex in favour of
>something sane, like <base>r<text>, 2r11001 = 8r31 = 25 = 16r19.

For some reason, I've never had cause to write numbers in (say) base 19.
I wonder if the added generality really buys you anything, given that it
does introduce a new class of subtle errors.  (How many programs would
notice if 16r19 was mistyped as 15r19?  Or 19r16?)
-- 
That's not a joke, that's      |     Henry Spencer at U of Toronto Zoology
NASA.  -Nick Szabo             | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/30/89)

In article <20989@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>... move toward abstracts.  Those of you who are trying to design `D'
>(or `P') might consider dumping 0-octal and 0x-hex in favour of
>something sane, like <base>r<text>, 2r11001 = 8r31 = 25 = 16r19.

Don't forget to support negative bases, and (oo, oo!) while you're at
it how about Fibonacci numeration systems.  Think how useful they
would be!

bengsig@oracle.nl (Bjorn Engsig) (11/30/89)

Article <11708@smoke.BRL.MIL> by gwyn@brl.arpa (Doug Gwyn) says:
|Don't forget to support negative bases, and [...] Fibonacci numeration systems.
And do include the Roman numbers:

#define I	1
#define II	2
#define III	3
#define IV	4
 ...
-- 
Bjorn Engsig,	Domain:		bengsig@oracle.nl, bengsig@oracle.com
		Path:		uunet!mcsun!orcenl!bengsig

peter@ficc.uu.net (Peter da Silva) (12/01/89)

While you're being silly, Doug, you could have pointed out that 0rXXXXX is
used for Roman numerals in the Olivetti Frobozz-1 C Compiler, revision
buggywhip-7 or later.

Seriously, binary would be a stunningly cheap innovation. Generalised bases
is a neat idea, and the XXrYYYY syntax is easily the best suggested so
far.
-- 
`-_-' Peter da Silva <peter@ficc.uu.net> <peter@sugar.lonestar.org>.
 'U`  --------------  +1 713 274 5180.
"The basic notion underlying USENET is the flame."
	-- Chuq Von Rospach, chuq@Apple.COM 

gwyn@smoke.BRL.MIL (Doug Gwyn) (12/02/89)

In article <7157@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>While you're being silly, Doug, ...

I wasn't being silly.  I was trying to make a point about "neat ideas".

>Seriously, binary would be a stunningly cheap innovation. Generalised bases
>is a neat idea, and the XXrYYYY syntax is easily the best suggested so
>far.

Fibonacci bases are more useful than this,
and why limit variable radix to (a) constants and (b) positive radix?
Those are of comparatively little utility.

I don't think the idea was so "neat".

anw@maths.nott.ac.uk (Dr A. N. Walker) (12/04/89)

In article <1989Nov29.164913.1794@utzoo.uucp> henry@utzoo.uucp (Henry
Spencer) writes:
>In article <20989@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>> [proposes]	       <base>r<text>, 2r11001 = 8r31 = 25 = 16r19.
> [introduces]  a new class of subtle errors.  (How many programs would
>notice if 16r19 was mistyped as 15r19?  Or 19r16?)

	Many moons ago, when my students were writing their programs
in a sane language such as Chris suggests, it took me *ages* to spot
the bug in [re-written in the D or P idiom!]:

		int a[20];
		for (r = 1; r <= 10; r++)
			a[2r-1] = r;
		/* Bzzt!  Core dropped! Subscript out of bounds! */

Well, r runs from 1 to 10, so 2r-1 runs from 1 to 19, so that should
be OK.  You used the same array name, didn't you?  No mis-typings?
Semi-colons all in the right place.  Hmm.  Umm.  Shouldn't there be
a * between 2 and r?  I'm surprised the compiler accepted that, quite
neat getting implicit multiplication.

	CLANG!  2r-1 means -1 in binary.  (Actually, it should still be
a syntax error, but one can see why a compiler might allow it.)

-- 
Andy Walker, Maths Dept., Nott'm Univ., UK.
anw@maths.nott.ac.uk

karl@haddock.ima.isc.com (Karl Heuer) (12/05/89)

In article <11726@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>Fibonacci bases are more useful than this, and why limit variable radix to
>(a) constants and (b) positive radix?  Those are of comparatively little
>utility.

Because, with that limitation, there exists a simple notation that works (the
proposed NrNNN).  Why does strtol() have the same limitation, after all?

I like the idea of generalized radix (for D; it's too late for C) because it
includes the three common non-decimal radices (2, 8, 16) and because it does
so with a single syntax.  (C currently handles only two of these, and in the
process uses two different notations, one of them rather counterintuitive.)
The fact that the same feature would allow base 21 is only marginally
relevant.  To quote Chris Torek, "it is often better to get rid of specifics
and move toward abstracts."

In fact, if the syntax would permit it cleanly, I wouldn't have an upper limit
of 36, either.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

karl@haddock.ima.isc.com (Karl Heuer) (12/05/89)

In article <1989Nov29.164913.1794@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>For some reason, I've never had cause to write numbers in (say) base 19.

Interestingly enough, I once needed to write some constants whose natural
radix was 64 (and, due to the context, none of the radix-64 digits would ever
exceed the value of 'Z').  When I tried to make use of the arbitrary-radix
feature built into the language I was using at the time (using the notation
ddddB64), it triggered a compiler bug.

>I wonder if the added generality really buys you anything, given that it
>does introduce a new class of subtle errors.  (How many programs would
>notice if 16r19 was mistyped as 15r19?  Or 19r16?)

It doesn't seem any worse than the problem of accidentally putting a leading
zero on a number intended to be decimal.  Anyway, a partial solution is to
have the compiler optionally warn about the use of an "obscure" radix.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
(Bonus question: identify the language, operating system, and university where
I had use for radix 64.  No, I *don't* mean radix 40 aka RAD50.)

greim@sbsvax.UUCP (Michael Greim) (12/05/89)

In article <15348@haddock.ima.isc.com>, karl@haddock.ima.isc.com (Karl Heuer) writes:
> In article <1989Nov29.164913.1794@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
> >For some reason, I've never had cause to write numbers in (say) base 19.
> 
> Interestingly enough, I once needed to write some constants whose natural
> radix was 64 (and, due to the context, none of the radix-64 digits would ever
> exceed the value of 'Z').  When I tried to make use of the arbitrary-radix
> feature built into the language I was using at the time (using the notation
> ddddB64), it triggered a compiler bug.
If I recall correctly (the manual is nowhere near) DEC uses numbers with
radix 36 in the names for their fonts for the graphic system VWS, which
runs on VMS on MicroVaxes.
I was never curious enough to decipher the number, though. I have a
define "my_font01=[DEC's font name]", and that's all I care about the
numbers.

	Michael