HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Calculate min/max values for (un)signed integral number of up to 64 bits

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
numberbitsminmaxforcalculatevaluessignedintegral

Problem

This question is a follow up of Calculate min/max values for signed or unsigned integral number with any valid number of bits (up to 64)

I was answering the question Given two int values, return the one closer to 10, and I indicated that something like the following snippet of code could be a different approach for solving the problem.

In the original question, it turned out I had made a mistake, but since there were already some answers, I've decided to post a follow up question with the fixes.

Can this be done in a more efficient or more elegant way?

public class Bits
{
    public static void MinMaxI(ulong _bits, out long _min, out long _max)
    {
        // ? unsigned range with at least one value bit
        if (_bits  64)
        {
            throw new System.ArgumentOutOfRangeException("_bits", _bits,
             String.Format("2  64)
        {
            throw new System.ArgumentOutOfRangeException("_bits", _bits,
             String.Format("2  64)
        {
            throw new System.ArgumentOutOfRangeException("_bits", _bits,
             String.Format("2  64)
        {
            throw new System.ArgumentOutOfRangeException("_bits", _bits,
             String.Format("1 <= _bits <= 64"));
        }

        return _bits == 64 ? ~(ulong)0 : ~(~(ulong)0 << (int)_bits);
    }
}

Solution

Your argument validation could be de-duplicated.

Here, take a look:

MinMaxI:
    if (_bits  64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("2  64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("2  64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("2  64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("1 <= _bits <= 64"));
    }


They're practically the same!

I'd make a method like this (I'm not really familiar with C# syntax, so let me know if I made a mistake)

private static void validateBitsArgument(ulong _bits, ulong min, ulong max)
{
    if (_bits  max)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("{0} <= _bits <= {1}", min, max));
    }
}


And then include it like this:

public class Bits
{
    public static void MinMaxI(ulong _bits, out long _min, out long _max)
    {
        validateBitsArgument(_bits, 2, 64);

        _min = ~(long)0  max)
        {
            throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("{0} <= _bits <= {1}", min, max));
        }
    }
}


And voila, shorter code.

Code Snippets

MinMaxI:
    if (_bits < 2 || _bits > 64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("2 <= _bits <= 64"));
    }

MinI:
    if (_bits < 2 || _bits > 64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("2 <= _bits <= 64"));
    }

MaxI:
    if (_bits < 2 || _bits > 64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("2 <= _bits <= 64"));
    }

MaxN:
    if (_bits < 1 || _bits > 64)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("1 <= _bits <= 64"));
    }
private static void validateBitsArgument(ulong _bits, ulong min, ulong max)
{
    if (_bits < min || _bits > max)
    {
        throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("{0} <= _bits <= {1}", min, max));
    }
}
public class Bits
{
    public static void MinMaxI(ulong _bits, out long _min, out long _max)
    {
        validateBitsArgument(_bits, 2, 64);

        _min = ~(long)0 << (int)(_bits - 1);
        _max = -1 - _min;
    }


    public static long MinI(ulong _bits)
    {
        validateBitsArgument(_bits, 2, 64);

        return ~(long)0 << (int)(_bits - 1);
    }


    public static long MaxI(ulong _bits)
    {
        validateBitsArgument(_bits, 2, 64);

        return -1 - (~(long)0 << (int)(_bits - 1));
    }


    public static ulong MaxN(ulong _bits)
    {
        validateBitsArgument(_bits, 1, 64);

        return _bits == 64 ? ~(ulong)0 : ~(~(ulong)0 << (int)_bits);
    }

    private static void validateBitsArgument(ulong _bits, ulong min, ulong max)
    {
        if (_bits < min || _bits > max)
        {
            throw new System.ArgumentOutOfRangeException("_bits", _bits,
         String.Format("{0} <= _bits <= {1}", min, max));
        }
    }
}

Context

StackExchange Code Review Q#87829, answer score: 3

Revisions (0)

No revisions yet.