Task: Find first and last set bit of a long integer




Go: package main

import (
    "fmt"
    "math/big"
)

const (
    mask0, bit0 = (1 << (1 << iota)) - 1, 1 << iota
    mask1, bit1
    mask2, bit2
    mask3, bit3
    mask4, bit4
    mask5, bit5
)

func rupb(x uint64) (out int) {
    if x == 0 {
        return -1
    }
    if x&^mask5 != 0 {
        x >>= bit5
        out |= bit5
    }
    if x&^mask4 != 0 {
        x >>= bit4
        out |= bit4
    }
    if x&^mask3 != 0 {
        x >>= bit3
        out |= bit3
    }
    if x&^mask2 != 0 {
        x >>= bit2
        out |= bit2
    }
    if x&^mask1 != 0 {
        x >>= bit1
        out |= bit1
    }
    if x&^mask0 != 0 {
        out |= bit0
    }
    return
}

func rlwb(x uint64) (out int) {
    if x == 0 {
        return 0
    }
    if x&mask5 == 0 {
        x >>= bit5
        out |= bit5
    }
    if x&mask4 == 0 {
        x >>= bit4
        out |= bit4
    }
    if x&mask3 == 0 {
        x >>= bit3
        out |= bit3
    }
    if x&mask2 == 0 {
        x >>= bit2
        out |= bit2
    }
    if x&mask1 == 0 {
        x >>= bit1
        out |= bit1
    }
    if x&mask0 == 0 {
        out |= bit0
    }
    return
}





func rupbBig(x *big.Int) int {
    return x.BitLen() - 1
}




func rlwbBig(x *big.Int) int {
    if x.BitLen() < 2 {
        return 0
    }
    bit := uint(1)
    mask := big.NewInt(1)
    var ms []*big.Int
    var y, z big.Int
    for y.And(x, z.Lsh(mask, bit)).BitLen() == 0 {
        ms = append(ms, mask)
        mask = new(big.Int).Or(mask, &z)
        bit <<= 1
    }
    out := bit
    for i := len(ms) - 1; i >= 0; i-- {
        bit >>= 1
        if y.And(x, z.Lsh(ms[i], out)).BitLen() == 0 {
            out |= bit
        }
    }
    return int(out)
}

func main() {
    show()
    showBig()
}

func show() {
    fmt.Println("uint64:")
    fmt.Println("power              number  rupb  rlwb")
    const base = 42
    n := uint64(1)
    for i := 0; i < 12; i++ {
        fmt.Printf("%d^%02d %19d %5d %5d\n", base, i, n, rupb(n), rlwb(n))
        n *= base
    }
}

func showBig() {
    fmt.Println("\nbig numbers:")
    fmt.Println("  power                               number  rupb  rlwb")
    base := big.NewInt(1302)
    n := big.NewInt(1)
    for i := 0; i < 12; i++ {
        fmt.Printf("%d^%02d %36d %5d %5d\n", base, i, n, rupbBig(n), rlwbBig(n))
        n.Mul(n, base)
    }
}


Java: public class FirstLastBits {

    
    public static int mssb(int x) {
        return Integer.highestOneBit(x);
    }

    public static long mssb(long x) {
        return Long.highestOneBit(x);
    }

    public static int mssb_idx(int x) {
        return Integer.SIZE - 1 - Integer.numberOfLeadingZeros(x);
    }

    public static int mssb_idx(long x) {
        return Long.SIZE - 1 - Long.numberOfLeadingZeros(x);
    }

    public static int mssb_idx(BigInteger x) {
	return x.bitLength() - 1;
    }

    
    public static int lssb(int x) {
        return Integer.lowestOneBit(x);
    }

    public static long lssb(long x) {
        return Long.lowestOneBit(x);
    }

    public static int lssb_idx(int x) {
        return Integer.numberOfTrailingZeros(x);
    }

    public static int lssb_idx(long x) {
        return Long.numberOfTrailingZeros(x);
    }

    public static int lssb_idx(BigInteger x) {
	return x.getLowestSetBit();
    }

    public static void main(String[] args) {
        System.out.println("int:");
        int n1 = 1;
        for (int i = 0; ; i++, n1 *= 42) {
            System.out.printf("42**%d = %10d(x%08x): M x%08x(%2d) L x%03x(%2d)\n",
                              i, n1, n1,
                              mssb(n1), mssb_idx(n1),
                              lssb(n1), lssb_idx(n1));
            if (n1 >= Integer.MAX_VALUE / 42)
                break;
        }
        System.out.println();
        System.out.println("long:");
        long n2 = 1;
        for (int i = 0; ; i++, n2 *= 42) {
            System.out.printf("42**%02d = %20d(x%016x): M x%016x(%2d) L x%06x(%2d)\n",
                              i, n2, n2,
                              mssb(n2), mssb_idx(n2),
                              lssb(n2), lssb_idx(n2));
            if (n2 >= Long.MAX_VALUE / 42)
                break;
        }
	System.out.println();
	System.out.println("BigInteger:");
	BigInteger n3 = BigInteger.ONE;
	BigInteger k = BigInteger.valueOf(1302);
	for (int i = 0; i < 10; i++, n3 = n3.multiply(k)) {
	    System.out.printf("1302**%02d = %30d(x%28x): M %2d L %2d\n",
			      i, n3, n3,
			      mssb_idx(n3),
			      lssb_idx(n3));
	}
    }
}