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/integer/IntegerProperties.lvt
namespace Eccelerators.BitTwiddling.Integer
/**
* Provides common properties and transformations for fixed-width 32-bit
* integers.
*
* Functions use int only where signed interpretation is part of the contract;
* raw bit patterns and non-negative magnitudes use uint.
*/
class IntegerProperties
{
/**
* Returns a mask representing the sign of value.
*
* Non-negative values return 0. Negative values return -1, whose 32-bit
* two's-complement representation has every bit set.
*/
public static fn SignMask[](value: int) int
{
return value >> 31
}
/**
* Returns true when x and y have different signs.
*
* Zero is non-negative, so zero and a negative value have opposite signs.
*/
public static fn HaveOppositeSigns[](x: int, y: int) bool
{
return (x ^ y) < 0
}
/**
* Returns the unsigned magnitude of value.
*
* Returning uint allows the magnitude of -2147483648 to be represented as
* 0x80000000 instead of overflowing a signed int.
*/
public static fn AbsoluteValueBits[](value: int) uint
{
var mask: int = value >> 31
return ((value + mask) ^ mask) as uint
}
/**
* Returns the smaller of signed values x and y.
*/
public static fn Minimum[](x: int, y: int) int
{
if (x < y)
{
return x
}
return y
}
/**
* Returns the larger of signed values x and y.
*/
public static fn Maximum[](x: int, y: int) int
{
if (x > y)
{
return x
}
return y
}
/**
* Returns true when value is an exact positive power of two.
*
* Zero returns false. Every valid power of two has exactly one set bit.
*/
public static fn IsPowerOfTwo[](value: uint) bool
{
return (value != (0 as uint)) &&
((value & (value - (1 as uint))) == (0 as uint))
}
/**
* Returns the smallest power of two greater than or equal to value.
*
* Zero returns 1. Values above 0x80000000 return 0 because the mathematical
* result cannot be represented by uint. Existing powers of two are returned
* unchanged.
*/
public static fn RoundUpToPowerOfTwo[](value: uint) uint
{
if (value == (0 as uint))
{
return 1
}
if (value > (0x80000000 as uint))
{
return 0
}
var workingValue: uint = value - (1 as uint)
workingValue = workingValue | (workingValue >> 1)
workingValue = workingValue | (workingValue >> 2)
workingValue = workingValue | (workingValue >> 4)
workingValue = workingValue | (workingValue >> 8)
workingValue = workingValue | (workingValue >> 16)
return workingValue + (1 as uint)
}
/**
* Interprets the low bitWidth bits of value as a signed two's-complement
* number and sign-extends it to int.
*
* Valid widths are 1 through 32. Bits above bitWidth are ignored. Invalid
* widths return 0.
*/
public static fn SignExtend[](value: uint, bitWidth: int) int
{
if ((bitWidth < 1) || (bitWidth > 32))
{
return 0
}
if (bitWidth == 32)
{
return value as int
}
var signBit: uint = (1 as uint) << (bitWidth - 1)
var widthMask: uint = ((1 as uint) << bitWidth) - (1 as uint)
var maskedValue: uint = value & widthMask
return ((maskedValue ^ signBit) - signBit) as int
}
}