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