![]() |
|
|
#12 | |
|
∂2ω=0
Sep 2002
República de California
101101011101112 Posts |
Quote:
1. Freeware; 2. No compile/install (with all the attendant versioning issues, nontrivial for us Luddites using older OSes and such) needed; 3. No internet pipe needed; 4. Decent set of number-theoretic tools such as gcd, powmod, modest factoring capability (say numbers somewhere in the 50-100 digit range); 5. User can add/modify functionality as desired. No disputing that bc has some major drawbacks - lack of bitwise operations and binary shift being an obvious one. That needs workarounds to get acceptably fast functionality, for, say bit-counting - if you try to use the 1-bit-a-time bits() function in my above post on any input beyond 1000 bits or so, things slow to a crawl. So here are 2 alternatives - on a 500000-bit input, on my Core2-based Macbook classic, bits2() needs around 60 seconds to count the bits; bits3() needs under 5, still slow, but a nice speedup, and none of this is intended for serious work in the megabit size range: Code:
/* Power-of-2 powers-of-2 needed by fast bit-counting function: pow2[i] = 2^2^i: */
pow2[0] = 2;
pow2[1] = pow2[0]^2;
pow2[2] = pow2[1]^2;
[etc]
/* Recursive divide-and-conquer version asymptotically faster than 1-bit-at-a-time: */
define bits2(n) {
auto i,j,tmp;
tmp = abs(n);
if(tmp < 2) return tmp;
i = 0; j = 0; /* j has current bitcount */
while(tmp >= pow2[i]) {
i += 1;
}
j += 2^(i-1);
tmp /= pow2[i-1];
j += bits2(tmp);
return(j);
}
/* Multiply much faster than divide, so this version faster than recursive div-based one: */
define bits3(n) {
auto i,j,tmp,tm2;
n = abs(n);
if(n < 2) return n;
i = 0; j = 1; tmp = 1; /* j has current bitcount */
while(n >= pow2[i++]) { }
while(i--) {
tm2 = tmp*pow2[i];
if(tm2 < n) {
j += 2^i;
tmp = tm2;
}
}
return(j);
}
Last fiddled with by ewmayer on 2017-10-12 at 02:59 |
|
|
|
|
|
|
#13 |
|
Sep 2002
Database er0rr
3,739 Posts |
I found this page which might be of interest to you: http://www.numbertheory.org/gnubc/bc_programs.html
|
|
|
|
|
|
#14 |
|
Sep 2002
Database er0rr
3,739 Posts |
Another way to find how many bits a number is, is to load mathlib and use logs, and afterwards use "scale=0" to get back to using integers
Code:
bc -lq l(2^50000)/l(2)+1 50001.00000000000000052166 |
|
|
|
|
|
#15 | |
|
Sep 2002
Database er0rr
3,739 Posts |
Quote:
Code:
l(2^44497-1)/l(2)+1 44498.00000000000000046424 l(2^44497)/l(2)+1 44498.00000000000000046424 ![]() Here is my bit-counter: Code:
define count_bits(n) {
auto m, i;
m = 1;
i = 0;
while( m <= n ) {
m *= 2;
i += 1;
}
return(i);
}
Last fiddled with by paulunderwood on 2017-10-12 at 17:52 |
|
|
|
|
|
|
#16 |
|
Sep 2002
Database er0rr
3,739 Posts |
Code:
length(n)/l(2)*l(10) ![]() Code:
define fast_count_bits(n) {
auto r;
scale=0;
r = length(n);
scale=20;
r = r/l(2)*l(10);
scale = 0;
r = r - r%1;
while (2^r > n) { r -= 1 }
return(r+1)
}
Last fiddled with by paulunderwood on 2017-10-12 at 20:24 |
|
|
|
|
|
#17 | |
|
Sep 2002
Database er0rr
1110100110112 Posts |
Quote:
Last fiddled with by paulunderwood on 2017-10-12 at 20:59 |
|
|
|
|
|
|
#18 | |
|
∂2ω=0
Sep 2002
República de California
103×113 Posts |
Quote:
Re. loading the mathlib, it would definitely be nice to have both pure-int and arbitrary-prec float avaialable and playing nice side-by-side, but doesn't that wreck some key number-theoretic functions? E.g. mod no longer works as expected. |
|
|
|
|
|
|
#19 | |
|
Sep 2002
Database er0rr
3,739 Posts |
Quote:
|
|
|
|
|
|
|
#20 |
|
∂2ω=0
Sep 2002
República de California
103·113 Posts |
So when mixing int and float operations we just need to make sure the former save and restore scale - nice. On large (by bc standards) inputs your bit-counter is 10-20% faster than my pure-int one; this sort of function may be a worst-case scenario here due to bc's lack of built-in bitwise functionality.
|
|
|
|
|
|
#21 |
|
∂2ω=0
Sep 2002
República de California
103·113 Posts |
Paul, you were just one little step away from 'virtually instantaneous' in your FP-based bit-counting trials ... Since length() works in both int ('bc') and float ('bc -l') modes to count decimal digits and is very fast (validating the surmise that bc's internals are decimal-multiprecision-based), in either mode we can simply supplement that with a fixed-point-mul/div by a scaled version of log2(10), whose rightmost digit is a rounded-up truncation of said logarithm:
define bits(n) { return length(n)*3321928095/1000000000; } |
|
|
|
|
|
#22 | |
|
Sep 2002
Database er0rr
3,739 Posts |
Quote:
Code:
bits(2^100) 102 bits(2^101) 102 bits(2^102) 102 The revised function, assuming no mathlib loaded or mathlib loaded and scale=0: Code:
define fast_count_bits(n) {
auto r;
r = length(n)*3321928095/1000000000;
while ( 2^r > n ) { r -= 1; }
return(r+1)
}
Last fiddled with by paulunderwood on 2017-10-14 at 03:02 |
|
|
|
|
![]() |
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Array vs Hash Table vs Map for QS | Sam Kennedy | Programming | 1 | 2012-12-25 23:25 |
| Init.d Script for MPrime | CrashM | Software | 0 | 2012-05-18 01:01 |
| array of bits | Citrix | Programming | 2 | 2005-08-21 20:06 |
| Ubasic Array question | rn0dal | Programming | 6 | 2004-09-15 14:57 |