Raul wrote:
>  twosC=: #:~ 2 #~ 1 + {:@$@#:

The clause {:@$@#: does a lot of work (computationally speaking, not 
notationally speaking) to determine the number of bits required.  There is a 
cheaper way.

But the problem with “cheaper ways” is I always have to come up with them and 
then teach J what they are.  Just for once, I’d like J to teach *me* how to do 
it better.

Well, today is that day:

           2&#. b. _1
        ($&2@>:@(2&(<.@^.))@(1&>.)@(>./)@:|@, #: ]) :.(2&#.)

Thus [1]:

           ndr NB. Number of Digits Required
        10&$: :( >:@<.@^. 1 >. >./@:|@, )

And so:

           twosC =: #:~ 2 #~ 1 + {:@$@#:
           twosC2 =: #:~ 2 #~ 1 + 2&ndr

           (twosC2 -: twosC) i:4
        1
        
Comparing performance:

           A=:i:1e7 NB. Unnecessarily large
           Q=:10 timespacex&> '{:@$@#: A';'2&ndr A’

           Q
        0.501709 5.36873e8
        0.204981 5.36873e8

           0.01 round %/Q   [  load'numeric'
        2.45 1

Of course this difference is only showing up with unrealistically large inputs, 
and in that case will be swamped by the calculation and manifestation of the 
final  #:  array in twosC … but, it was a fun opportunity to show off  n&#. b. 
_1  (one of my favorite J tricks).

-Dan

[1]  I really think ndr or some variant should be included in the standard 
library. I also think I shouldn’t have to  load’numeric’  to get something as 
useful and frequently-needed as “round”.


----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to