Livt packages

Eccelerators.BitTwiddling

Version 0.1.1

Readable 32-bit bit manipulation, counting, scanning, permutation, and arithmetic utilities for Livt.

Published files (26)

src/counting/BitCounting.lvt

namespace Eccelerators.BitTwiddling.Counting

/**
 * Provides population-count and parity operations for unsigned 32-bit words.
 *
 * PopCount is the recommended library entry point. The explicitly named
 * iterative and parallel variants remain public for migration examples and
 * for comparing the hardware structures produced from each algorithm.
 */
class BitCounting
{
    /**
     * Counts the set bits in value and returns a result from 0 through 32.
     *
     * This recommended implementation uses a fixed sequence of mask, shift,
     * and add stages, so its source-level work does not depend on the input.
     */
    public static fn PopCount[](value: uint) int
    {
        var workingValue: uint = value
        workingValue = workingValue -
            ((workingValue >> 1) & (0x55555555 as uint))
        workingValue = (workingValue & (0x33333333 as uint)) +
            ((workingValue >> 2) & (0x33333333 as uint))
        workingValue = (workingValue + (workingValue >> 4)) &
            (0x0F0F0F0F as uint)
        workingValue = workingValue + (workingValue >> 8)
        workingValue = workingValue + (workingValue >> 16)
        return (workingValue & (0x3F as uint)) as int
    }

    /**
     * Counts the set bits in value using Brian Kernighan's iterative method.
     *
     * Each iteration clears one set bit. The iteration count therefore equals
     * the returned population count and ranges from 0 through 32.
     */
    public static fn PopCountIterative[](value: uint) int
    {
        var workingValue: uint = value
        var count: int = 0

        while (workingValue != (0 as uint))
        {
            workingValue = workingValue & (workingValue - (1 as uint))
            count = count + 1
        }

        return count
    }

    /**
     * Counts the set bits in value with a parallel mask-and-add reduction.
     *
     * This educational variant currently has the same implementation as the
     * recommended PopCount API and returns a value from 0 through 32.
     */
    public static fn PopCountParallel[](value: uint) int
    {
        var workingValue: uint = value
        workingValue = workingValue -
            ((workingValue >> 1) & (0x55555555 as uint))
        workingValue = (workingValue & (0x33333333 as uint)) +
            ((workingValue >> 2) & (0x33333333 as uint))
        workingValue = (workingValue + (workingValue >> 4)) &
            (0x0F0F0F0F as uint)
        workingValue = workingValue + (workingValue >> 8)
        workingValue = workingValue + (workingValue >> 16)
        return (workingValue & (0x3F as uint)) as int
    }

    /**
     * Returns true when value contains an odd number of set bits.
     *
     * The implementation folds the word with XOR operations and does not
     * compute the complete population count.
     */
    public static fn HasOddParity[](value: uint) bool
    {
        var folded: uint = value
        folded = folded ^ (folded >> 16)
        folded = folded ^ (folded >> 8)
        folded = folded ^ (folded >> 4)
        folded = folded ^ (folded >> 2)
        folded = folded ^ (folded >> 1)
        return (folded & (1 as uint)) != (0 as uint)
    }
}