I don't think there's a violation of a uniqueness constraint. Consider: for a positive scalar argument y, then #:y is unique (trivially). And, in the approach we're discussing, when the argument is negative, as in #:-y, then the result is just -#:y . Therefore, #:-y is also unique, and furthermore distinct from #:y. That is: the results of #: are always strictly non-positive or non-negative. No individual result of #: will contain both positive and negative digits.
I also wouldn't mind your proposal of (#:-y) = _1 , #: y , but I think the -#:y approach can claim some advantages. Given: ab0 =: *@:] * (#.^:_1 |) ab1 =: (_1 * 0 > ]) ,"0 1^:(0~:+/@:[) #.^:_1 NB. Distilled from your code We note first that ab0 is simpler than ab1. That means it's easier to understand and implement (and debug). Second, the results of ab0 are easier to interpret. Knowing the definition of both verbs, you could tell me what decimal number _1 _2 _3 represents on sight, but with _1 8 7 7 you'd have to do some mental calculation (they both represent the quantity _123). This advantage is cumulative when reasoning about arrays of results (i.e., in J). Third, critically, the shape of ab0's results doesn't change with the sign of its argument. This is important and valuable in a J context. For example: _5 + 6 1 _5 +&.(2&ab0 :. #.) 6 1 _5 +&.(2&ab1 :. #.) 6 |length error | _5 +&.(2&ab1 :.#.)6 Moreover, this feature is particularly important for digit-arrays, because J pads on the right, but in the positional number system, right-padding is anathema. That is, prepending a _1 exacerbates a problem #: already has (by allowing more opportunities for it to arise): my_array =: 2 ab1 3 2 1 my_array =: my_array , 2 ab1 _1 _2 _3 #. my_array 6 4 2 _1 _2 _3 NB. Ouch! Where'd my 3 2 1 go? Finally, I'd argue that the -#:y also makes intuitive sense: _123 means "subtract one hundred, [subtract] two tens, and [subtract] three units". Though this is subjective, it does allow one to reason about negative numbers in a straightforward and expected way: _123 + 456 333 _1 _2 _3 + 4 5 6 3 3 3 10 #. _1 _2 _3 + 4 5 6 333 _123 * 456 _56088 _1 _2 _3 * 456 _456 _912 _1368 10 #. _1 _2 _3 * 456 _56088 BTW, though I am using decimal examples, all these comments apply equally to binary numbers, and every other base. -Dan -----Original Message----- From: programming-boun...@jsoftware.com [mailto:programming-boun...@jsoftware.com] On Behalf Of Marshall Lochbaum Sent: Monday, December 12, 2011 2:55 PM To: Programming forum Subject: Re: [Jprogramming] How #: should have been designed The problem with this is that we would prefer not to use negative numbers in antibase, since they can violate uniqueness of base representation. There's really no solution to this--my recommendation is to just never feed negative numbers to #: . However, an option that minimizes negative numbers (and is very close to simply having two's complement base representation) is to make the first digit negative if the number is negative. Thus #: becomes base =. [: |."_1@:> |.@(#:`(_1,#:)@.(<&0))&.> Basically, use J's #: , and prepend a _1 if the input is negative. Then reverse, box, open everything for fill, and reverse again. base i:5 _1 0 1 1 _1 1 0 0 0 _1 0 1 0 _1 1 0 0 0 _1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 #. base i:5 _5 _4 _3 _2 _1 0 1 2 3 4 5 Marshall On Mon, Dec 12, 2011 at 2:09 PM, Dan Bron <j...@bron.us> wrote: > Maybe we should explore a different track. Forget all about the history of > computing hardware, and the advantages of one representation over another > when designing circuits. In purely mathematical terms, what are the > decimal > digits of the base-10 number -123 ? > > Working backwards: > > _123 NB. begin > -123 NB. notation->operation > _1 * 123 NB. definition of - > _1 * (1 * 10^2) + (2 * 10^1) + ( 3 * 10^0) NB. positional number > notation > (_1 * 10^2) + (_2 * 10^1) + (_3 * 10^0) NB. distribution of * over + > _1 _2 _3 +/ . * 10^2 1 0 NB. array simplification > 10 #. _1 _2 _3 NB. definition of #. > > Thus, to satisfy the purposes of inversion, we should have: > [all examples from here on are purely theoretical, and the > results differ in the extant implementations of J]: > > 10 #.^:_1: _123 > _1 _2 _3 > > And, analogously in base 2: > > 2 #.^:_1: 2b_101 NB. 2b_101 is J's notation > for -101 in base 2 > _1 0 _1 > #: 2b_101 NB. #: <=> 2&#.^:_1: > _1 0 _1 > #: _5 NB. _5 <=> 2b_101 (numbers > are analytic) > _1 0 _1 > > QED.* > > -Dan > > * Backwards compatibility notwithstanding > > PS: What implications does this have for modulus, as in _10 | 123 ? > > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm