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

Content added Content deleted
m (syntax highlighting fixup automation)
Line 39:
=={{header|11l}}==
 
<langsyntaxhighlight lang="11l">L(i) 6
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)))</langsyntaxhighlight>
 
{{out}}
Line 64:
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Unchecked_Conversion;
Line 132:
Put_Result (Value => 42 ** A);
end loop;
end Find_Last_Bit;</langsyntaxhighlight>
{{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'''<langsyntaxhighlight lang="algol68">INT lbits width = UPB []BOOL(LBITS(2r0));
 
OP LWB = (BITS in x)INT: bits width - RUPB in x;
Line 231:
# WHILE # out bit /= 2r0 DO SKIP OD;
ABS out # EXIT #
FI;</langsyntaxhighlight>'''File: test.Find_first_and_last_set_bit.a68'''<langsyntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
 
MODE LBITS = LONG BITS;
Line 275:
prod *:= zoom
OD
)</langsyntaxhighlight>
{{out}}
<pre>
Line 304:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">loop, 12{
First := Last := ""
n:=42**(A_Index-1)
Line 312:
Res .= 42 "^" A_Index-1 " --> First : " First " , Last : " Last "`n"
}
MsgBox % Res</langsyntaxhighlight>
{{out}}
<pre>42^0 --> First : 0 , Last : 0
Line 329:
 
=={{header|BASIC256}}==
<langsyntaxhighlight BASIC256lang="basic256">print "INT: find first & last set bit"
p = 1
for j = 0 to 5
Line 345:
return (i & -i)
end function
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 359:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdint.h>
 
Line 405:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 419:
===GCC extension===
{{works with|GCC}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <limits.h>
 
Line 468:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 496:
=={{header|D}}==
(This task is not complete, the second part will be added later.)
<langsyntaxhighlight lang="d">import std.stdio, core.bitop, std.bigint;
 
void main() {
Line 507:
x, size_t.sizeof * 8, x, bsr(x), bsf(x));
}
}</langsyntaxhighlight>
{{out}}
On a 32 bit system:
Line 533:
{{libheader| System.SysUtils}}
{{libheader| Velthuis.BigIntegers}} Thanks for Rudy Velthuis for Velthuis.BigIntegers[https://github.com/rvelthuis/DelphiBigNumbers].
<syntaxhighlight lang="delphi">
<lang Delphi>
program Find_first_and_last_set_bit_of_a_long_integer;
 
Line 568:
 
readln;
end.</langsyntaxhighlight>
{{out}}
<pre> 1 0000000000000000000000000000000000000000000000000000000000000001 MSB: 0 LSB: 0
Line 586:
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.
 
<langsyntaxhighlight lang="fortran">program bits
implicit none
integer :: n = 1, i
Line 594:
n = 42 * n
end do
end program</langsyntaxhighlight>
{{out}}
<pre>
Line 611:
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.
 
<langsyntaxhighlight 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
Line 756:
end do
 
end program find_set_bits</langsyntaxhighlight>
 
{{out}}
Line 790:
=={{header|FreeBASIC}}==
{{trans|Python}}
<langsyntaxhighlight lang="freebasic">Function MSB(i As Integer) As Integer
Return Len(Bin(i))-1
End Function
Line 803:
p *= 42
Next j
Sleep</langsyntaxhighlight>
{{out}}
<pre>
Line 823:
=={{header|Go}}==
{{trans|ALGOL 68}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 958:
n.Mul(n, base)
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 997:
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.
 
<langsyntaxhighlight Iconlang="icon">link printf,hexcvt
 
procedure main()
Line 1,055:
}
return mask # return pre-built data
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 1,080:
Implementation:
 
<langsyntaxhighlight lang="j">lwb=: 0:
upb=: (#: i: 1:)"0
rlwb=: #@#:"0 - 1:
rupb=: rlwb - upb</langsyntaxhighlight>
 
Notes:
Line 1,093:
lwb is the required name for the index of "first set bit in a binary value". This is always zero here. Here's why:
 
<langsyntaxhighlight Jlang="j"> #: 7
1 1 1
#: 8
Line 1,102:
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</langsyntaxhighlight>
 
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 1,110:
Example use:
 
<langsyntaxhighlight lang="j"> (,.lwb,.upb,.rlwb,.rupb) <.i.@>.&.(42&^.) 2^64
1 0 0 0 0
42 0 4 5 1
Line 1,137:
13999413527763489727269395457024 0 93 103 10
18227236413148063624904752885045248 0 102 113 11
23731861809918778839625988256328912896 0 112 124 12</langsyntaxhighlight>
 
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 1,151:
* least significant bit is bit 0 (such that bit ''i'' always has value 2<sup>i</sup>, and the result is independent of integer type width)
* when the integer 0 is given, mssb() and lssb() both return no bits set; mssb_idx() and lssb_idx() will return -1 and the integer type width, respectively
<langsyntaxhighlight lang="java">public class FirstLastBits {
 
// most significant set bit
Line 1,228:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,270:
 
'''Module''':
<langsyntaxhighlight lang="julia">module Bits
 
export lwb, upb
Line 1,277:
upb(n) = 8 * sizeof(n) - leading_zeros(n) - 1
 
end # module Bits</langsyntaxhighlight>
 
'''Main''':
<langsyntaxhighlight lang="julia">using Main.Bits
 
# Using the built-in functions `leading_zeros` and `trailing_zeros`
Line 1,293:
for n in int128"1302" .^ (0:11)
@printf(" %-40i | %-3i | %-3i\n", n, lwb(n), upb(n))
end</langsyntaxhighlight>
 
{{out}}
Line 1,328:
=={{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:
<langsyntaxhighlight lang="scala">// version 1.1.0
 
import java.math.BigInteger
Line 1,367:
pow1302 *= big1302
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,394:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">MSB[n_]:=BitLength[n]-1
LSB[n_]:=IntegerExponent[n,2]</langsyntaxhighlight>
 
<pre>Map[{#,"MSB:",MSB[#],"LSB:",LSB[#]}&,
Line 1,415:
=={{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]].
<langsyntaxhighlight lang="c">long
msb(GEN n)
{
Line 1,425:
{
return vali(n);
}</langsyntaxhighlight>
 
This version uses GP. It works on arbitrary-length integers; GP cannot directly work on wordsize integers except in a <code>vecsmall</code>.
<langsyntaxhighlight lang="parigp">lsb(n)=valuation(n,2);
msb(n)=#binary(n)-1;</langsyntaxhighlight>
 
=={{header|Perl}}==
This is simple and works with both native and bigint numbers.
<langsyntaxhighlight lang="perl">sub msb {
my ($n, $base) = (shift, 0);
$base++ while $n >>= 1;
Line 1,441:
my $n = shift;
msb($n & -$n);
}</langsyntaxhighlight>
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.
<langsyntaxhighlight lang="perl">sub bi_msb { # Input should be a Math::BigInt object
length(shift->as_bin)-3;
}</langsyntaxhighlight>
With native ints, this meets the task description assuming a 64-bit Perl:
<langsyntaxhighlight lang="perl">sub msb64 {
my($n, $pos) = (shift, 0);
die "n must be a 64-bit integer)" if $n > ~0;
Line 1,458:
if (($n & 0x8000000000000000) == 0) { $pos += 1; $n <<= 1; }
63-$pos;
}</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 1,464:
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.
<!--<langsyntaxhighlight Phixlang="phix">-->
<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,500:
<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>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,523:
=== mpfr/gmp ===
{{libheader|Phix/mpfr}}
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<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,544:
<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>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,565:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de msb (N)
(dec (length (bin (abs N)))) )
 
(de lsb (N)
(length (stem (chop (bin N)) "1")) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">(for N (1 42 717368321110468608 291733167875766667063796853374976)
(tab (33 6 6) N (lsb N) (msb N)) )</langsyntaxhighlight>
{{out}}
<pre> 1 0 0
Line 1,581:
=={{header|Python}}==
{{works with|Python|2.7+ and 3.1+}}
<langsyntaxhighlight lang="python">def msb(x):
return x.bit_length() - 1
 
Line 1,593:
for i in range(6):
x = 1302 ** i
print("%20d MSB: %2d LSB: %2d" % (x, msb(x), lsb(x)))</langsyntaxhighlight>
{{out}}
<pre>
Line 1,611:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require rnrs/arithmetic/bitwise-6)
Line 1,617:
(define x (expt 42 n))
(list n (bitwise-first-bit-set x) (- (integer-length x) 1)))
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="racket">
'((0 0 0)
(1 1 5)
Line 1,640:
(18 18 97)
(19 19 102))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 1,646:
 
Raku integers are arbitrary sized, and the lsb and msb methods are built-in.
<syntaxhighlight lang="raku" perl6line>sub table ($base,$power) {
my $digits = ($base ** $power).chars;
printf "%{$digits}s lsb msb\n", 'number';
Line 1,656:
 
table 42, 20;
table 1302, 20;</langsyntaxhighlight>
{{out}}
<pre> number lsb msb
Line 1,712:
 
A fair amount of coding was added to align and/or center the displaying of the numbers for the output.
<langsyntaxhighlight lang="rexx">/*REXX program finds the first and last set bit of "integer" and "long integer". */
parse arg digs . /*obtain optional argument from the CL.*/
if digs=='' | digs=="," then digs= 40 /*Not specified? Then use the default.*/
Line 1,739:
rlwb: arg #; call n2b #; if #==0 then return 0; return L - length( strip( bits, 'T', 0))
rupb: arg #; call n2b #; if #==0 then return -1; return L - 1
sep: arg _; say @d || _ || @4 || _ || @4 || _ || copies(@, length( n2b(10**d) )); return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the internal default inputs:}}
 
Line 1,799:
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">def msb(x)
x.bit_length - 1
end
Line 1,815:
x = 1302 ** i
puts "%20d MSB: %2d LSB: %2d" % [x, msb(x), lsb(x)]
end</langsyntaxhighlight>
 
{{out}}
Line 1,839:
most- and least-significant set bit in a binary value expressed in LSB 0 bit numbering.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "bigint.s7i";
 
Line 1,870:
" MSB: " <& rupb(bigNum) lpad 2 <& " LSB: " <& rlwb(bigNum) lpad 2);
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 1,895:
Sidef has arbitrary sized integers.
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func msb(n) {
var b = 0
while(n >>= 1) { ++b }
Line 1,903:
func lsb(n) {
msb(n & -n)
}</langsyntaxhighlight>
 
Test cases:
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func table (base,power) {
var digits = length(base**power)
printf("%#{digits}s lsb msb\n", 'number')
Line 1,917:
 
table(42, 20)
table(1302, 20)</langsyntaxhighlight>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc lwb {x} {
if {$x == 0} {return -1}
set n 0
Line 1,938:
}
return $n
}</langsyntaxhighlight>
Code to use the above:
<langsyntaxhighlight lang="tcl">package require Tcl 8.6; # For convenient bit string printing
 
proc powsTo {pow bits} {
Line 1,963:
printPows 42 [powsTo 42 [expr {$tcl_platform(wordSize) * 8}]]
puts "Powers of 1302 up to 128 bits"
printPows 1302 [powsTo 1302 128]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,994:
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight lang="ecmascript">import "/big" for BigInt
import "/fmt" for Fmt
 
Line 2,012:
Fmt.print("1302^$d = $,25s rupb: $2s rlwb: $2s", i, x, rupb.call(x), rlwb.call(x))
x = x * 1302
}</langsyntaxhighlight>
 
{{out}}
Line 2,036:
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="yabasic">print "INT: find first & last set bit"
p = 1
for j = 0 to 5
Line 2,051:
sub LSB(i)
return MSB(and(i,-i))
end sub</langsyntaxhighlight>
{{out}}
<pre>
Line 2,067:
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)
 
<langsyntaxhighlight lang="z80">;;;;;;;;;;;;;;;;;;; HEADER ;;;;;;;;;;;;;;;;;;;
read "\SrcCPC\winape_macros.asm"
read "\SrcCPC\MemoryMap.asm"
Line 2,119:
 
read "\SrcCPC\winape_stringop.asm"
read "\SrcCPC\winape_showhex.asm"</langsyntaxhighlight>
{{out}}
<pre>00
Line 2,128:
{{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.
<langsyntaxhighlight lang="zkl">fcn lsb(n){ n.bitAnd(n.bitNot()+1).log2() }
fcn msb(n){ n.log2() }
 
Line 2,136:
p,n,n, msb(n), lsb(n)));
if (n>=(1).MAX / 42) break;
}</langsyntaxhighlight>
{{out}}
<pre>