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

Reply via email to