Find first and last set bit of a long integer: Difference between revisions
Find first and last set bit of a long integer (view source)
Revision as of 20:46, 10 December 2023
, 6 months agoAdded XPL0 example.
m (→{{header|REXX}}: changed font size for the output section.) |
(Added XPL0 example.) |
||
(24 intermediate revisions by 13 users not shown) | |||
Line 39:
=={{header|11l}}==
<
V x = Int(42 ^ i)
print(‘#10 MSB: #2 LSB: #2’.format(x, bsr(x), bsf(x)))
Line 45:
L(i) 6
V x = Int64(1302 ^ i)
print(‘#20 MSB: #2 LSB: #2’.format(x, bsr(x), bsf(x)))</
{{out}}
Line 64:
=={{header|Ada}}==
<
with Ada.Integer_Text_IO;
with Ada.Unchecked_Conversion;
Line 132:
Put_Result (Value => 42 ** A);
end loop;
end Find_Last_Bit;</
{{out}}
<pre>
Line 153:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.3.5 algol68g-2.3.5].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: Template.Find_first_and_last_set_bit.a68'''<
OP LWB = (BITS in x)INT: bits width - RUPB in x;
Line 231:
# WHILE # out bit /= 2r0 DO SKIP OD;
ABS out # EXIT #
FI;</
MODE LBITS = LONG BITS;
Line 275:
prod *:= zoom
OD
)</
{{out}}
<pre>
Line 302:
18227236413148063624904752885045248| 11 |113 |111000001010101100000100010100010101100000011011010011001110101111101110010001100000011001010001101001100000000000
</pre>
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">msb: function [x]-> dec size as.binary x
lsb: function [x]-> msb and x neg x
loop 0..5 'i [
x: 42 ^ i
print [pad to :string x 10 "-->" "MSB:" pad.right to :string (msb x) 2 "- LSB:" lsb x]
]
print ""
loop 0..5 'i [
x: 1302 ^ i
print [pad to :string x 17 "-->" "MSB:" pad.right to :string (msb x) 2 "- LSB:" lsb x]
]</syntaxhighlight>
{{out}}
<pre> 1 --> MSB: 0 - LSB: 0
42 --> MSB: 5 - LSB: 1
1764 --> MSB: 10 - LSB: 2
74088 --> MSB: 16 - LSB: 3
3111696 --> MSB: 21 - LSB: 4
130691232 --> MSB: 26 - LSB: 5
1 --> MSB: 0 - LSB: 0
1302 --> MSB: 10 - LSB: 1
1695204 --> MSB: 20 - LSB: 2
2207155608 --> MSB: 31 - LSB: 3
2873716601616 --> MSB: 41 - LSB: 4
3741579015304032 --> MSB: 51 - LSB: 5</pre>
=={{header|AutoHotkey}}==
<
First := Last := ""
n:=42**(A_Index-1)
Line 312 ⟶ 345:
Res .= 42 "^" A_Index-1 " --> First : " First " , Last : " Last "`n"
}
MsgBox % Res</
{{out}}
<pre>42^0 --> First : 0 , Last : 0
Line 326 ⟶ 359:
42^10 --> First : 10 , Last : 53
42^11 --> First : 11 , Last : 59</pre>
=={{header|BASIC256}}==
<syntaxhighlight lang="basic256">print "INT: find first & last set bit"
p = 1
for j = 0 to 5
print rjust(p,9); " "; rjust(ToBinary(p),29,0); " MSB: "; rjust(MSB(p),2); " LSB: "; rjust(LSB(p),2)
p *= 42
next j
print
end
function MSB(i)
return length(ToBinary(i))-1
end function
function LSB(i)
return (i & -i)
end function
</syntaxhighlight>
{{out}}
<pre>
INT: find first & last set bit
1 00000000000000000000000000001 MSB: 0 LSB: 1
42 00000000000000000000000101010 MSB: 5 LSB: 2
1764 00000000000000000011011100100 MSB: 10 LSB: 4
74088 00000000000010010000101101000 MSB: 16 LSB: 8
3111696 00000001011110111101100010000 MSB: 21 LSB: 16
130691232 00111110010100011000010100000 MSB: 26 LSB: 32
</pre>
=={{header|C}}==
<
#include <stdint.h>
Line 374 ⟶ 437:
return 0;
}</
{{out}}
<pre>
Line 388 ⟶ 451:
===GCC extension===
{{works with|GCC}}
<
#include <limits.h>
Line 437 ⟶ 500:
return 0;
}</
{{out}}
<pre>
Line 465 ⟶ 528:
=={{header|D}}==
(This task is not complete, the second part will be added later.)
<
void main() {
Line 476 ⟶ 539:
x, size_t.sizeof * 8, x, bsr(x), bsf(x));
}
}</
{{out}}
On a 32 bit system:
Line 502 ⟶ 565:
{{libheader| System.SysUtils}}
{{libheader| Velthuis.BigIntegers}} Thanks for Rudy Velthuis for Velthuis.BigIntegers[https://github.com/rvelthuis/DelphiBigNumbers].
<syntaxhighlight lang="delphi">
program Find_first_and_last_set_bit_of_a_long_integer;
Line 537 ⟶ 600:
readln;
end.</
{{out}}
<pre> 1 0000000000000000000000000000000000000000000000000000000000000001 MSB: 0 LSB: 0
Line 551 ⟶ 614:
17080198121677824 0000000000111100101011100101100110000101101111000110010000000000 MSB: 53 LSB: 10
717368321110468608 0000100111110100100110101010111111110000111010000110100000000000 MSB: 59 LSB: 11</pre>
=={{header|Forth}}==
{{works with|gforth|0.7.3}}
<syntaxhighlight lang="Forth">: bin. base @ 2 base ! swap u. base ! ;
: lwb ( n -- u )
0 swap
begin
dup 1 and 0= while
1 rshift
swap 1+ swap
repeat drop ;
: upb ( n -- u )
-1 swap
begin
dup 0<> while
1 rshift
swap 1+ swap
repeat drop ;
: Find_first_and_last_set_bit_of_a_long_integer
1 6 0 do
dup dup dup dup
cr 10 .r ." : " ." MSB:" upb 2 .r ." , LSB:" lwb 2 .r ." , %" bin.
42 *
loop drop ;
Find_first_and_last_set_bit_of_a_long_integer</syntaxhighlight>
{{out}}
<pre> 1: MSB: 0, LSB: 0, %1
42: MSB: 5, LSB: 1, %101010
1764: MSB:10, LSB: 2, %11011100100
74088: MSB:16, LSB: 3, %10010000101101000
3111696: MSB:21, LSB: 4, %1011110111101100010000
130691232: MSB:26, LSB: 5, %111110010100011000010100000 ok
</pre>
=={{header|Fortran}}==
Since the Fortran 2008 standard, the language has LEADZ and TRAILZ intrinsic functions that yield respectively the number of leading (i.e. HSB) and trailing (LSB) zero bits. This gives an immediate solution to the task.
<
implicit none
integer :: n = 1, i
Line 563 ⟶ 667:
n = 42 * n
end do
end program</
{{out}}
<pre>
Line 573 ⟶ 677:
111110010100011000010100000 5 26
</pre>
=== By divide and conquer ===
Even though Fortran has intrinsic functions, and modern machines have special instructions for the task, it still seems worthwhile to write out functions.
One thing that is evident, if you study the various ways to implement these functions, is that Fortran is ill suited, in a way most high-level languages have been ill suited since the beginning of time: they do not have built in ''unsigned'' integers with ''overflow explicitly allowed''. ISO standard C does (and thus so does ATS, because its integers are exactly C integers). But this is unusual, outside of C and its relatives, and (I would imagine) owes to C's origins as a replacement for assembly language.
<syntaxhighlight lang="fortran">! As was already pointed out, Fortran has intrinsic functions that
! should compile to efficient code, such as a single machine
! instruction. But it seems profitable to have written implementations
! according to the task description.
! Here, by the way, is a page devoted to the topic of finding the LS1B
! and MS1B positions:
! https://www.chessprogramming.org/index.php?title=BitScan&oldid=22495#With_separated_LS1B
! I am uncertain what the "lwb" and "upb" are supposed to mean, but I
! imagine it is to isolate the bit. I do this below using
! bit-twiddling methods, *before* doing binary searches to find the
! positions of the bits.
module bit_thingies_for_rosetta_code
! INT64 is the largest integer kind standardized in ISO_FORTRAN_ENV,
! although 128-bit integers are available with gfortran on AMD64. I
! shall stick with INT64; the principles do not differ.
use, intrinsic :: iso_fortran_env, only: int64
implicit none
integer(kind = int64), parameter :: most_negative = ishft (1_int64, 63)
integer(kind = int64), parameter :: mask1 = &
& int (b'1010101010101010101010101010101010101010101010101010101010101010', &
& kind = int64)
integer(kind = int64), parameter :: mask2 = &
& int (b'1100110011001100110011001100110011001100110011001100110011001100', &
& kind = int64)
integer(kind = int64), parameter :: mask3 = &
& int (b'1111000011110000111100001111000011110000111100001111000011110000', &
& kind = int64)
integer(kind = int64), parameter :: mask4 = &
& int (b'1111111100000000111111110000000011111111000000001111111100000000', &
& kind = int64)
integer(kind = int64), parameter :: mask5 = &
& int (b'1111111111111111000000000000000011111111111111110000000000000000', &
& kind = int64)
integer(kind = int64), parameter :: mask6 = &
& int (b'1111111111111111111111111111111100000000000000000000000000000000', &
& kind = int64)
contains
! LS1B-position by binary search. This method is MUCH improved by
! first isolating the least significant 1-bit, so I do that. This
! action makes the masks more effective.
elemental function rlwb (n) result (i)
integer(kind = int64), value :: n
integer :: i
if (n == most_negative) then
!
! With the most negative two's complement number, one cannot
! trust Fortran to do arithmetic as one intends. Thus this
! branch. (There would be no such problem with *unsigned*
! integers in C; these are required by the standard to overflow
! and underflow freely.)
!
! If you take into account the task's restriction to positive
! integers, then of course this case never occurs, and you can
! leave out the branch.
!
i = 63
else
! Isolate the least significant 1-bit. This method is specific
! for two's complement. Your platform is very unlikely not to
! be two's complement.
n = iand (n, -n)
i = 0_int64
if (iand (n, not (mask6)) == 0) i = 32_int64
if (iand (n, not (mask5)) == 0) i = i + 16_int64
if (iand (n, not (mask4)) == 0) i = i + 8_int64
if (iand (n, not (mask3)) == 0) i = i + 4_int64
if (iand (n, not (mask2)) == 0) i = i + 2_int64
if (iand (n, not (mask1)) == 0) i = i + 1_int64
end if
end function rlwb
! MS1B-position by binary search. This method is MUCH improved by
! first isolating the most significant 1-bit, so I do that. This
! action makes the masks more effective.
elemental function rupb (n) result (i)
integer(kind = int64), value :: n
integer :: i
if (ibits (n, 63, 1) /= 0) then
! The task restricts itself to positive integers, but I shall
! do a branch for negative numbers.
i = 0_int64
else if (ibits (n, 62, 1) /= 0) then
! Also, in Fortran one cannot safely add one to every 63-bit
! number, so another special branch.
i = 1_int64
else
! Fill all bits to the right of the MS1B.
n = ior (n, ishft (n, -1))
n = ior (n, ishft (n, -2))
n = ior (n, ishft (n, -4))
n = ior (n, ishft (n, -8))
n = ior (n, ishft (n, -16))
n = ior (n, ishft (n, -32))
! Isolate the most significant 1-bit.
n = ishft (n + 1, -1)
i = 0_int64
if (iand (n, mask6) /= 0) i = 32_int64
if (iand (n, mask5) /= 0) i = i + 16_int64
if (iand (n, mask4) /= 0) i = i + 8_int64
if (iand (n, mask3) /= 0) i = i + 4_int64
if (iand (n, mask2) /= 0) i = i + 2_int64
if (iand (n, mask1) /= 0) i = i + 1_int64
end if
end function rupb
end module bit_thingies_for_rosetta_code
program find_set_bits
use, intrinsic :: iso_fortran_env, only: int64
use, non_intrinsic :: bit_thingies_for_rosetta_code
implicit none
integer :: i
integer(kind = int64) :: n
write (*, '(A70)') "Using intrinsic functions TRAILZ and LEADZ"
n = 1_int64
do i = 0, 11
write (*, '(B0.64, 2(" ", I2))') n, trailz (n), 63 - leadz (n)
n = 42_int64 * n
end do
write (*, '()')
write (*, '(A70)') "Using binary search"
n = 1_int64
do i = 0, 11
write (*, '(B0.64, 2(" ", I2))') n, rlwb (n), rupb (n)
n = 42_int64 * n
end do
end program find_set_bits</syntaxhighlight>
{{out}}
<pre>$ gfortran -std=f2018 find_set_bits.f90 && ./a.out
Using intrinsic functions TRAILZ and LEADZ
0000000000000000000000000000000000000000000000000000000000000001 0 0
0000000000000000000000000000000000000000000000000000000000101010 1 5
0000000000000000000000000000000000000000000000000000011011100100 2 10
0000000000000000000000000000000000000000000000010010000101101000 3 16
0000000000000000000000000000000000000000001011110111101100010000 4 21
0000000000000000000000000000000000000111110010100011000010100000 5 26
0000000000000000000000000000000101000111001010111111101001000000 6 32
0000000000000000000000000011010110101101001101110000111010000000 7 37
0000000000000000000010001100111001101011000010000110000100000000 8 43
0000000000000001011100011101110110001111010111111110101000000000 9 48
0000000000111100101011100101100110000101101111000110010000000000 10 53
0000100111110100100110101010111111110000111010000110100000000000 11 59
Using binary search
0000000000000000000000000000000000000000000000000000000000000001 0 0
0000000000000000000000000000000000000000000000000000000000101010 1 5
0000000000000000000000000000000000000000000000000000011011100100 2 10
0000000000000000000000000000000000000000000000010010000101101000 3 16
0000000000000000000000000000000000000000001011110111101100010000 4 21
0000000000000000000000000000000000000111110010100011000010100000 5 26
0000000000000000000000000000000101000111001010111111101001000000 6 32
0000000000000000000000000011010110101101001101110000111010000000 7 37
0000000000000000000010001100111001101011000010000110000100000000 8 43
0000000000000001011100011101110110001111010111111110101000000000 9 48
0000000000111100101011100101100110000101101111000110010000000000 10 53
0000100111110100100110101010111111110000111010000110100000000000 11 59</pre>
=={{header|FreeBASIC}}==
{{trans|Python}}
<syntaxhighlight lang="freebasic">Function MSB(i As Integer) As Integer
Return Len(Bin(i))-1
End Function
Function LSB(i As Integer) As Integer
Return MSB(i And -i)
End Function
Dim As Integer p = 1
For j As Integer = 0 To 11
Print Using "################## & MSB: ## LSB: ##"; p; Bin(p,64); MSB(p); LSB(p)
p *= 42
Next j
Sleep</syntaxhighlight>
{{out}}
<pre>
1 0000000000000000000000000000000000000000000000000000000000000001 MSB: 0 LSB: 0
42 0000000000000000000000000000000000000000000000000000000000101010 MSB: 5 LSB: 1
1764 0000000000000000000000000000000000000000000000000000011011100100 MSB: 10 LSB: 2
74088 0000000000000000000000000000000000000000000000010010000101101000 MSB: 16 LSB: 3
3111696 0000000000000000000000000000000000000000001011110111101100010000 MSB: 21 LSB: 4
130691232 0000000000000000000000000000000000000111110010100011000010100000 MSB: 26 LSB: 5
5489031744 0000000000000000000000000000000101000111001010111111101001000000 MSB: 32 LSB: 6
230539333248 0000000000000000000000000011010110101101001101110000111010000000 MSB: 37 LSB: 7
9682651996416 0000000000000000000010001100111001101011000010000110000100000000 MSB: 43 LSB: 8
406671383849472 0000000000000001011100011101110110001111010111111110101000000000 MSB: 48 LSB: 9
17080198121677824 0000000000111100101011100101100110000101101111000110010000000000 MSB: 53 LSB: 10
717368321110468608 0000100111110100100110101010111111110000111010000110100000000000 MSB: 59 LSB: 11
</pre>
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
local fn IntegerToBinaryStr( x as NSInteger ) as CFStringRef
CFStringRef resultStr = @""
while ( x )
resultStr = fn StringByAppendingString( fn StringWithFormat( @"%lu", x && 1 ), resultStr )
x = x >> 1
wend
end fn = resultStr
local fn FirstAndLastBit
NSInteger i, p = 1
for i = 0 to 11
CFStringRef binaryStr = fn IntegerToBinaryStr(p)
printf @"%20lld %-62s MSB: %2lld LSB: %2lld", p, fn StringUTF8String( binaryStr ), len( binaryStr ) - 1, i
p = p * 42
next
end fn
fn FirstAndLastBit
HandleEvents
</syntaxhighlight>
{{output}
<pre>
1 1 MSB: 0 LSB: 0
42 101010 MSB: 5 LSB: 1
1764 11011100100 MSB: 10 LSB: 2
74088 10010000101101000 MSB: 16 LSB: 3
3111696 1011110111101100010000 MSB: 21 LSB: 4
130691232 111110010100011000010100000 MSB: 26 LSB: 5
5489031744 101000111001010111111101001000000 MSB: 32 LSB: 6
230539333248 11010110101101001101110000111010000000 MSB: 37 LSB: 7
9682651996416 10001100111001101011000010000110000100000000 MSB: 43 LSB: 8
406671383849472 1011100011101110110001111010111111110101000000000 MSB: 48 LSB: 9
17080198121677824 111100101011100101100110000101101111000110010000000000 MSB: 53 LSB: 10
717368321110468608 100111110100100110101010111111110000111010000110100000000000 MSB: 59 LSB: 11
</pre>
=={{header|Go}}==
{{trans|ALGOL 68}}
<
import (
Line 711 ⟶ 1,073:
n.Mul(n, base)
}
}</
{{out}}
<pre>
Line 750 ⟶ 1,112:
Instead of this, to meet the spirit of the task, these lsb and msb routines are generalized to reduce the integer in blocks of bits and then zoom in on the desired bit by binary search (i.e. successively looking a blocks that are half the size again). The exponent for the initial power used to create the masks does not need to be itself a power of two. The xsb_initial procedure uses introspection to determine the word size of a basic integer type. This is used to build a mask that fits within the basic word size of the implementation. In this way we won't create unnecessary large integers through implicit type conversions.
<
procedure main()
Line 808 ⟶ 1,170:
}
return mask # return pre-built data
end</
{{libheader|Icon Programming Library}}
Line 833 ⟶ 1,195:
Implementation:
<
upb=: (#: i: 1:)"0
rlwb=: #@#:"0 - 1:
rupb=: rlwb - upb</
Notes:
Line 846 ⟶ 1,208:
lwb is the required name for the index of "first set bit in a binary value". This is always zero here. Here's why:
<
1 1 1
#: 8
Line 855 ⟶ 1,217:
1 1 0 0 0 1 0 1 0 1
#:123456789123456789123456789x
1 1 0 0 1 1 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 1 1 1 0 0 0 1 1 1 0 1 1 0 0 0 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 1 1 1 0 0 0 1 0 1 0 1</
The the first '''set''' bit in J's binary representation for a positive integer is always the first bit of that integer (there's an exception for zero, because it has no first set bit, but that's outside the domain of this task). That said, note that this would not hold for an arbitrary integer in a list of integers. But bit representations of lists of integers is outside the scope of this task.
Line 863 ⟶ 1,225:
Example use:
<
1 0 0 0 0
42 0 4 5 1
Line 890 ⟶ 1,252:
13999413527763489727269395457024 0 93 103 10
18227236413148063624904752885045248 0 102 113 11
23731861809918778839625988256328912896 0 112 124 12</
Note, in the above sentences, the rightmost part of each sentence is about generating an arbitrary sequence of values. The phrase <.i.@>.&.(42&^.) 2^64 generates the sequence 1 42 1764 74088 3111696 130691232 ... and the phrase i.@x:@>.&.(1302&^.) 2^128 generates the sequence 1 1302 1695204 2207155608 ...
Line 898 ⟶ 1,260:
=={{header|Java}}==
{{works with|Java|1.5+}}
<syntaxhighlight lang="java">public class FirstAndLastBits {
public static long
if ( aNumber <= 0 ) {
throw new IllegalArgumentException("Number must be positive");
}
return Long.numberOfTrailingZeros(aNumber);
}
public static long MSB(Long aNumber) {
if ( aNumber <= 0 ) {
throw new IllegalArgumentException("Number must be positive");
}
return 63 - Long.numberOfLeadingZeros(aNumber);
}
public static long LSB(BigInteger aNumber) {
if ( aNumber.signum() <= 0 ) {
throw new IllegalArgumentException("Number must be positive");
}
return aNumber.getLowestSetBit();
}
public static long MSB(BigInteger aNumber) {
if ( aNumber.signum() <= 0 ) {
throw new IllegalArgumentException("Number must be positive");
}
return aNumber.bitLength() - 1;
}
public static void main(String[] aArgs) {
Long powerOf42 = 1L;
for ( int i = 0; i <= 11; i++ ) {
System.out.print(String.format("%-5s%-3s%s", "42 ^ ", i, " = "));
System.out.print(String.format("%1$" + 64 + "s", Long.toBinaryString(powerOf42)).replace(" ", "0"));
System.out.println(String.format("%s%-2s%s%-2s", " -> LSB: ", LSB(powerOf42), ", MSB: ", MSB(powerOf42)));
powerOf42 *= 42;
}
System.out.println();
BigInteger bigInteger1302 = BigInteger.valueOf(1302);
BigInteger powerOf1302 = BigInteger.ONE;
for ( int i = 0; i <= 6; i++ ) {
System.out.print(String.format("%-7s%s%s", "1302 ^ ", i, " = "));
System.out.print(String.format("%1$" + 64 + "s", powerOf1302.toString(2)).replace(" ", "0"));
String line = String.format("%s%-2s%s%-2s", " -> LSB: ", LSB(powerOf1302), ", MSB: ", MSB(powerOf1302));
System.out.println(line);
powerOf1302 = powerOf1302.multiply(bigInteger1302);
}
}
}</syntaxhighlight>
{{out}}
<pre>
42 ^ 0 = 0000000000000000000000000000000000000000000000000000000000000001 -> LSB: 0 , MSB: 0
42 ^ 1 = 0000000000000000000000000000000000000000000000000000000000101010 -> LSB: 1 , MSB: 5
42 ^ 2 = 0000000000000000000000000000000000000000000000000000011011100100 -> LSB: 2 , MSB: 10
42 ^ 3 = 0000000000000000000000000000000000000000000000010010000101101000 -> LSB: 3 , MSB: 16
42 ^ 4 = 0000000000000000000000000000000000000000001011110111101100010000 -> LSB: 4 , MSB: 21
42 ^ 5 = 0000000000000000000000000000000000000111110010100011000010100000 -> LSB: 5 , MSB: 26
42 ^ 6 = 0000000000000000000000000000000101000111001010111111101001000000 -> LSB: 6 , MSB: 32
42 ^ 7 = 0000000000000000000000000011010110101101001101110000111010000000 -> LSB: 7 , MSB: 37
42 ^ 8 = 0000000000000000000010001100111001101011000010000110000100000000 -> LSB: 8 , MSB: 43
42 ^ 9 = 0000000000000001011100011101110110001111010111111110101000000000 -> LSB: 9 , MSB: 48
42 ^ 10 = 0000000000111100101011100101100110000101101111000110010000000000 -> LSB: 10, MSB: 53
42 ^ 11 = 0000100111110100100110101010111111110000111010000110100000000000 -> LSB: 11, MSB: 59
1302 ^ 0 = 0000000000000000000000000000000000000000000000000000000000000001 -> LSB: 0 , MSB: 0
1302 ^ 1 = 0000000000000000000000000000000000000000000000000000010100010110 -> LSB: 1 , MSB: 10
1302 ^ 2 = 0000000000000000000000000000000000000000000110011101110111100100 -> LSB: 2 , MSB: 20
1302 ^ 3 = 0000000000000000000000000000000010000011100011101000010110011000 -> LSB: 3 , MSB: 31
1302 ^ 4 = 0000000000000000000000101001110100010110110110110111001100010000 -> LSB: 4 , MSB: 41
1302 ^ 5 = 0000000000001101010010101111001001000000000110110011001101100000 -> LSB: 5 , MSB: 51
1302 ^ 6 = 0100001110011011001011000001001000001010010101110100101001000000 -> LSB: 6 , MSB: 62
</pre>
Line 1,023 ⟶ 1,342:
'''Module''':
<
export lwb, upb
Line 1,030 ⟶ 1,349:
upb(n) = 8 * sizeof(n) - leading_zeros(n) - 1
end # module Bits</
'''Main''':
<
# Using the built-in functions `leading_zeros` and `trailing_zeros`
Line 1,046 ⟶ 1,365:
for n in int128"1302" .^ (0:11)
@printf(" %-40i | %-3i | %-3i\n", n, lwb(n), upb(n))
end</
{{out}}
Line 1,081 ⟶ 1,400:
=={{header|Kotlin}}==
As I have no idea what the difference is supposed to be between lwb/uwb and rlwb/ruwb (unless the former numbers bits from left to right), I have only provided implementations of the latter - using Java/Kotlin library functions - which seem to be all that is needed in any case to perform the task in hand:
<
import java.math.BigInteger
Line 1,120 ⟶ 1,439:
pow1302 *= big1302
}
}</
{{out}}
Line 1,147 ⟶ 1,466:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
LSB[n_]:=IntegerExponent[n,2]</
<pre>Map[{#,"MSB:",MSB[#],"LSB:",LSB[#]}&,
Line 1,168 ⟶ 1,487:
=={{header|PARI/GP}}==
This version uses PARI. These work on arbitrary-length integers; the implementation for wordsize integers would be identical to [[#C|C's]].
<
msb(GEN n)
{
Line 1,178 ⟶ 1,497:
{
return vali(n);
}</
This version uses GP. It works on arbitrary-length integers; GP cannot directly work on wordsize integers except in a <code>vecsmall</code>.
<
msb(n)=#binary(n)-1;</
=={{header|Perl}}==
This is simple and works with both native and bigint numbers.
<
my ($n, $base) = (shift, 0);
$base++ while $n >>= 1;
Line 1,194 ⟶ 1,513:
my $n = shift;
msb($n & -$n);
}</
With large bigints, this is much faster (while as_bin seems expensive, every Math::BigInt transaction has large overhead, so Perl ops on the binary string ends up being a huge win vs. anything doing shifts, ands, compares, etc.). If we want one function to work on both types, we could easily modify this to make a Math::BigInt object if the input isn't already one.
<
length(shift->as_bin)-3;
}</
With native ints, this meets the task description assuming a 64-bit Perl:
<
my($n, $pos) = (shift, 0);
die "n must be a 64-bit integer)" if $n > ~0;
Line 1,211 ⟶ 1,530:
if (($n & 0x8000000000000000) == 0) { $pos += 1; $n <<= 1; }
63-$pos;
}</
=={{header|Phix}}==
Line 1,217 ⟶ 1,536:
There is nothing like this already built in, so we will roll our own, in low-level assembly. <br>
Of course you would normally hide this sort of stuff out of sight, far away from the usual day-to-day code.
<!--<
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">msb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
Line 1,253 ⟶ 1,572:
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
{{out}}
<pre>
Line 1,276 ⟶ 1,595:
=== mpfr/gmp ===
{{libheader|Phix/mpfr}}
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 1,297 ⟶ 1,616:
<span style="color: #7060A8;">mpz_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1302</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
{{out}}
<pre>
Line 1,318 ⟶ 1,637:
=={{header|PicoLisp}}==
<
(dec (length (bin (abs N)))) )
(de lsb (N)
(length (stem (chop (bin N)) "1")) )</
Test:
<
(tab (33 6 6) N (lsb N) (msb N)) )</
{{out}}
<pre> 1 0 0
Line 1,334 ⟶ 1,653:
=={{header|Python}}==
{{works with|Python|2.7+ and 3.1+}}
<
return x.bit_length() - 1
Line 1,346 ⟶ 1,665:
for i in range(6):
x = 1302 ** i
print("%20d MSB: %2d LSB: %2d" % (x, msb(x), lsb(x)))</
{{out}}
<pre>
Line 1,362 ⟶ 1,681:
3741579015304032 MSB: 51 LSB: 5
</pre>
=={{header|Quackery}}==
Quackery numbers are BigInts.
<code>lsb</code> returns <code>-1</code> if passed <code>0</code>, which has no bits set.
<code>msb</code> returns <code>-1</code> if passed a negative number, which has no highest set bit, or <code>0</code>, which has no bits set.
The reverse functions <code>rlwb</code> and <code>rupb</code> are not meaningful for BigInts as they do not have a rightmost bit. (Well, they do because memory is finite, but the size limit is not fixed.)
<syntaxhighlight lang="Quackery"> [ dup 0 = iff
[ 1 - ] done
0 swap
[ dup 1 & not while
dip 1+
1 >>
again ]
drop ] is lsb ( n --> n )
[ -1 swap
[ dup 1 < not while
dip 1+
1 >>
again ]
drop ] is msb ( n --> n )
6 times
[ 42 i^ ** dup echo
say " msb:"
dup msb echo
say " lsb:"
lsb echo cr ]
cr
6 times
[ 1302 i^ ** dup echo
say " msb:"
dup msb echo
say " lsb:"
lsb echo cr ]</syntaxhighlight>
{{out}}
<pre>1 msb:0 lsb:0
42 msb:5 lsb:1
1764 msb:10 lsb:2
74088 msb:16 lsb:3
3111696 msb:21 lsb:4
130691232 msb:26 lsb:5
1 msb:0 lsb:0
1302 msb:10 lsb:1
1695204 msb:20 lsb:2
2207155608 msb:31 lsb:3
2873716601616 msb:41 lsb:4
3741579015304032 msb:51 lsb:5</pre>
=={{header|Racket}}==
<
#lang racket
(require rnrs/arithmetic/bitwise-6)
Line 1,370 ⟶ 1,745:
(define x (expt 42 n))
(list n (bitwise-first-bit-set x) (- (integer-length x) 1)))
</syntaxhighlight>
{{out}}
<
'((0 0 0)
(1 1 5)
Line 1,393 ⟶ 1,768:
(18 18 97)
(19 19 102))
</syntaxhighlight>
=={{header|Raku}}==
Line 1,399 ⟶ 1,774:
Raku integers are arbitrary sized, and the lsb and msb methods are built-in.
<syntaxhighlight lang="raku"
my $digits = ($base ** $power).chars;
printf "%{$digits}s lsb msb\n", 'number';
Line 1,409 ⟶ 1,784:
table 42, 20;
table 1302, 20;</
{{out}}
<pre> number lsb msb
Line 1,465 ⟶ 1,840:
A fair amount of coding was added to align and/or center the displaying of the numbers for the output.
<
parse arg digs . /*obtain optional argument from the CL.*/
if digs=='' | digs=="," then digs= 40 /*Not specified? Then use the default.*/
Line 1,475 ⟶ 1,850:
@d= copies(@, d) /*build part of the separator line. */
call sep '─┬─' /* ─┬─ is part of the separator line.*/
say center(base'**n (decimal)', d) ! center(
right(base"**n (binary)" , d+5) /*display the title for the output. */
call sep '─┼─' /* ─┼─ is part of the separator line.*/
call sep '─┴─' /* ─┴─ is part of the separator line.*/
end /*cycle*/
exit
/*──────────────────────────────────────────────────────────────────────────────────────*/
n2b: bits= word( strip( x2b( d2x( arg(1))), 'L', 0) 0, 1); L= length(bits); return bits
rlwb: arg #; call n2b #; if #==0 then return 0;
rupb: arg #; call n2b #; if #==0 then return -1;
sep: arg _; say @d || _ || @4 || _ || @4 || _ || copies(@, length( n2b(10**d) )); return</
{{out|output|text= when using the internal default inputs:}}
Line 1,497 ⟶ 1,873:
<pre style="font-size:75%">
─────────────────────────────────────────┬──────┬──────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─────────────────────────────────────────┼──────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0 │ 0 │ -1 │ 0
Line 1,530 ⟶ 1,906:
─────────────────────────────────────────┬──────┬──────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─────────────────────────────────────────┼──────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0 │ 0 │ -1 │ 0
Line 1,547 ⟶ 1,923:
23731861809918778839625988256328912896 │ 12 │ 124 │ 10001110110101001011100011111110101101101100001101011011001001101111110110111011000001001000010001101000010010001000000000000
─────────────────────────────────────────┴──────┴──────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
</pre>
=={{header|RPL}}==
≪ → n
≪ '''IF''' n #0 == '''THEN''' -1 '''ELSE'''
0 #1
'''WHILE''' n OVER AND #0 == '''REPEAT''' SL SWAP 1 + SWAP '''END'''
DROP '''END'''
≫ ≫ '<span style="color:blue">LWB</span>' STO
≪ → n
≪ '''IF''' n #0 == '''THEN''' -1 '''ELSE'''
63 #1 RR
'''WHILE''' n OVER AND #0 == '''REPEAT''' SR SWAP 1 - SWAP '''END'''
DROP '''END'''
≫ ≫ '<span style="color:blue">UPB</span>' STO
≪ { } 0 5 '''FOR''' j 42 j ^ R→B DUP <span style="color:blue">UPB</span> SWAP <span style="color:blue">LWB</span> R→C + '''NEXT''' ≫ EVAL
{{out}}
<pre>
1: { (0,0) (5,1) (10,2) (16,3) (21,4) (26,5) }
</pre>
=={{header|Ruby}}==
{{trans|Python}}
<
x.bit_length - 1
end
Line 1,567 ⟶ 1,964:
x = 1302 ** i
puts "%20d MSB: %2d LSB: %2d" % [x, msb(x), lsb(x)]
end</
{{out}}
Line 1,591 ⟶ 1,988:
most- and least-significant set bit in a binary value expressed in LSB 0 bit numbering.
<
include "bigint.s7i";
Line 1,622 ⟶ 2,019:
" MSB: " <& rupb(bigNum) lpad 2 <& " LSB: " <& rlwb(bigNum) lpad 2);
end for;
end func;</
{{out}}
Line 1,647 ⟶ 2,044:
Sidef has arbitrary sized integers.
{{trans|Perl}}
<
var b = 0
while(n >>= 1) { ++b }
Line 1,655 ⟶ 2,052:
func lsb(n) {
msb(n & -n)
}</
Test cases:
{{trans|Raku}}
<
var digits = length(base**power)
printf("%#{digits}s lsb msb\n", 'number')
Line 1,669 ⟶ 2,066:
table(42, 20)
table(1302, 20)</
=={{header|Tcl}}==
<
if {$x == 0} {return -1}
set n 0
Line 1,690 ⟶ 2,087:
}
return $n
}</
Code to use the above:
<
proc powsTo {pow bits} {
Line 1,715 ⟶ 2,112:
printPows 42 [powsTo 42 [expr {$tcl_platform(wordSize) * 8}]]
puts "Powers of 1302 up to 128 bits"
printPows 1302 [powsTo 1302 128]</
{{out}}
<pre>
Line 1,746 ⟶ 2,143:
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./big" for BigInt
var rupb = Fn.new { |x| (x is BigInt) ? x.bitLength - 1 :
var rlwb = Fn.new { |x| rupb.call(x & -x) }
Line 1,766 ⟶ 2,161:
Fmt.print("1302^$d = $,25s rupb: $2s rlwb: $2s", i, x, rupb.call(x), rlwb.call(x))
x = x * 1302
}</
{{out}}
Line 1,787 ⟶ 2,182:
1302^6 = 4,871,535,877,925,849,664 rupb: 62 rlwb: 6
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">include xpllib; \for Print
func UpB(N); \Return position of highest set bit
int N, C;
[C:= 0;
if N & $FFFF0000 then [C:= C+16; N:= N & $FFFF0000];
if N & $FF00FF00 then [C:= C+ 8; N:= N & $FF00FF00];
if N & $F0F0F0F0 then [C:= C+ 4; N:= N & $F0F0F0F0];
if N & $CCCCCCCC then [C:= C+ 2; N:= N & $CCCCCCCC];
if N & $AAAAAAAA then [C:= C+ 1];
return C;
];
func LwB(N); \Return position of lowest set bit
int N;
return UpB(N & -N);
int N, I;
[Print(" MSB LSB\n");
N:= 1;
for I:= 0 to 5 do
[Print("%10d %3d %3d\n", N, UpB(N), LwB(N));
N:= N*42;
];
]</syntaxhighlight>
{{out}}
<pre>
MSB LSB
1 0 0
42 5 1
1764 10 2
74088 16 3
3111696 21 4
130691232 26 5
</pre>
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="yabasic">print "INT: find first & last set bit"
p = 1
for j = 0 to 5
print p using("##########"), " MSB: ", MSB(p) using("##"), " LSB: ", LSB(p)
p = p * 42
next j
print
end
sub MSB(i)
return len(bin$(i))-1
end sub
sub LSB(i)
return MSB(and(i,-i))
end sub</syntaxhighlight>
{{out}}
<pre>
INT: find first & last set bit
1 MSB: 0 LSB: 0
42 MSB: 5 LSB: 1
1764 MSB: 10 LSB: 2
74088 MSB: 16 LSB: 3
3111696 MSB: 21 LSB: 4
130691232 MSB: 26 LSB: 5
</pre>
=={{header|Z80 Assembly}}==
This version works with 8-bit values and is simple enough, given the CPU's obvious affinity for manipulating 8-bit data. First we display the "least" set bit, then the "most" set bit. These are in terms of LSB-0 ordering, e.g. <code>%76543210</code> (where those numbers are bit positions rather than literals)
<syntaxhighlight lang="z80">;;;;;;;;;;;;;;;;;;; HEADER ;;;;;;;;;;;;;;;;;;;
read "\SrcCPC\winape_macros.asm"
read "\SrcCPC\MemoryMap.asm"
read "\SrcALL\winapeBuildCompat.asm"
;;;;;;;;;;;;;;;;;;; PROGRAM ;;;;;;;;;;;;;;;;;;;
org &1000
ld a,%00101111
push af
call lwb_8
call showhex
call newline
pop af
call upb_8
call showhex
ret
upb_8:
ld b,8
upb_8_again:
or a
rla
jr c,upb_8_done:
djnz upb_8_again
ld a,255 ;failure code
ret
upb_8_done:
dec b
ld a,b
ret
lwb_8:
ld bc,&0800 ;ld b,8 ld c,0
lwb_8_again:
or a
rra
jr c,lwb_8_done
inc c
djnz lwb_8_again
ld a,255 ;failure code
ret
lwb_8_done:
ld a,c
ret
read "\SrcCPC\winape_stringop.asm"
read "\SrcCPC\winape_showhex.asm"</syntaxhighlight>
{{out}}
<pre>00
05</pre>
=={{header|zkl}}==
{{trans|C}}
This uses the Int method log2 (== MSB position), which returns the log base 2 of self. log2 is implemented with shifts and ors (it is a 5 step loop (for 64 bit ints) which could obviously be unrolled). See http://graphics.stanford.edu/~seander/bithacks.html.
<
fcn msb(n){ n.log2() }
Line 1,799 ⟶ 2,322:
p,n,n, msb(n), lsb(n)));
if (n>=(1).MAX / 42) break;
}</
{{out}}
<pre>
|