Find first and last set bit of a long integer: Difference between revisions

m (Refactor Ruby loops by Integer#times)
Line 1,096:
 
=={{header|Phix}}==
Limiting efforts to=== machine-sized integers.<br> ===
Note that bigatoms are stored as bcd (binary coded decimal), fairly incompatible with any bitwise operations, and
bigints are stored as an array of 16-bit words, to preclude internal overflows. I suppose the latter could be
extended with bi_msb() and bi_lsb(), which perform a linear scan down the array and apply something similar to
the first non-zero encountered.
 
There is nothing like this already built in, so we will roll our own, in low-level assembly. Of course you would normally hide this sort of stuff out of sight, far away from the usual day-to-day code.
<lang Phix>function msb(integer i)
Line 1,156 ⟶ 1,151:
on 64-bit that results in 130691232 + ~7.3e-12 rather than the integer 130691232 exactly,
whereas repeated multiplication by 42 as shown keeps it integer for longer.
 
=== mpfr/gmp ===
<lang Phix>include mpfr.e -- 0.8.0+
 
function rupbz(mpz n)
integer res = mpz_sizeinbase(n,2)
while res!=0 and mpz_tstbit(n,res)=0 do
res -= 1
end while
return res
end function
 
function rlwbz(mpz n)
return mpz_scan1(n,0)
end function
 
mpz n = mpz_init(1)
for i = 0 to 12 do
printf(1,"1302^%02d %38s %5d %5d\n", {i,mpz_get_str(n), rupbz(n), rlwbz(n)})
mpz_mul_si(n,n,1302)
end for</lang>
{{out}}
<pre>
1302^00 1 0 0
1302^01 1302 10 1
1302^02 1695204 20 2
1302^03 2207155608 31 3
1302^04 2873716601616 41 4
1302^05 3741579015304032 51 5
1302^06 4871535877925849664 62 6
1302^07 6342739713059456262528 72 7
1302^08 8258247106403412053811456 82 8
1302^09 10752237732537242494062515712 93 9
1302^10 13999413527763489727269395457024 103 10
1302^11 18227236413148063624904752885045248 113 11
1302^12 23731861809918778839625988256328912896 124 12
</pre>
 
=={{header|PicoLisp}}==
7,822

edits