1. 程式人生 > >【筆記】Hacker's Delight - Power-Of-2 Boundaries

【筆記】Hacker's Delight - Power-Of-2 Boundaries

 Rounding Up/Down to a Multiple of a Known Power of 2(上下取整為2的n次方)

Rounding Down

/// <summary>
/// greatest power of 2 less than or equal to <paramref name="n"/>
/// </summary>
public static uint FloorPowerOf2(uint n)
{
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);
            
    return n - (n >> 1);
}

Rounding Up

/// <summary>
/// least power of 2 greater than or equal to <paramref name="n"/>
/// </summary>
public static uint CeilingPowerOf2(uint n)
{
    --n;
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);

    return n + 1;
}

Check Power-Of-2 Boundaries(檢驗是否為2的n次方)

/// <summary>
/// return true if n is power of 2
/// </summary>
public static bool IsPowerOf2(uint n)
    => n < 1u ? false : (n & (n - 1u)) == 0;

Rounding Up/Down Log2(x)

Rouding Down

/// <summary>
/// <seealso cref="Math.Floor(k)"/> (k = <seealso cref="Math.Log(n, 2)"/>)
/// </summary>
public static int FloorLog2(uint n)
{
    var c = -1;

    while (n > 0)
    {
        ++c;
        n >>= 1;
    }

    return c;
}

Rounding Up

/// <summary>
/// <seealso cref="Math.Ceiling(k)"/> (k = <seealso cref="Math.Log(n, 2)"/>)
/// </summary>
public static int CeilingLog2(uint n)
{
    var c = 0;
    while (n > 0)
    {
        ++c;
        n >>= 1;
    }

    return c;
}