method to get finger mask based on finger position

Posted on

Problem

Is there a more graceful way to structure the code below?

The fingerPosition values are increments of 1.

The fingerMask values start at 1, then 2 and then increment in multiples of 2.

    private int getFingerMask(int fingerPosition)
    {
        int fingerMask = 0;

        if (fingerPosition == 0)
        {
            fingerMask = 1;
        }
        else if (fingerPosition == 1)
        {
            fingerMask = 2;
        }
        else if (fingerPosition == 2)
        {
            fingerMask = 4;
        }
        else if (fingerPosition == 3)
        {
            fingerMask = 8;
        }
        else if (fingerPosition == 4)
        {
            fingerMask = 16;
        }
        else if (fingerPosition == 5)
        {
            fingerMask = 32;
        }
        else if (fingerPosition == 6)
        {
            fingerMask = 64;
        }
        else if (fingerPosition == 7)
        {
            fingerMask = 128;
        }
        else if (fingerPosition == 8)
        {
            fingerMask = 256;
        }
        else if (fingerPosition == 9)
        {
            fingerMask = 512;
        }

        return fingerMask;
    }

Solution

Yes, this can be done simply by using a power of 2.

private int getFingerMask(int fingerPosition)
{
    if (fingerPosition >= 0 && fingerPosition < 10)
    {
        return (int)Math.Pow(2, fingerPosition);
    }
    else
    {
        return 0;
    }
}

In addition to @Aaron’s answer, you can also use bit shifting. Also Naming Guidelines would expect the method to begin with a capital letter. This could also be reduced to a one-line method:

private int GetFingerMask(int fingerPosition) => (fingerPosition >= 0 && fingerPosition < 10) ? 1 << fingerPosition : 0;

These magic numbers are very magical. These feel like they should be enums:

// Perhaps there are better names for these positions? Thumb, Forefinger, etc.?
public enum FingerPosition
{
    Zero = 0,
    One,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine
}

// Again, better naming would be in order.
[Flags]
public enum FingerMask
{
    Unknown = 0,
    Zero = 1,
    One = 2,
    Two = 4,
    Three = 8,
    Four = 16,
    Five = 32,
    Six = 64,
    Seven = 128,
    Eight = 256,
    Nine = 512
}

Then something like a Dictionary to associate them as such:

private static readonly IDictionary<FingerPosition, FingerMask> _FingerMap = new Dictionary<FingerPosition, FingerMask>
{
    [FingerPosition.Zero] = FingerMask.Zero,
    [FingerPosition.One] = FingerMask.One,
    [FingerPosition.Two] = FingerMask.Two,
    [FingerPosition.Three] = FingerMask.Three,
    [FingerPosition.Four] = FingerMask.Four,
    [FingerPosition.Five] = FingerMask.Five,
    [FingerPosition.Six] = FingerMask.Six,
    [FingerPosition.Seven] = FingerMask.Seven,
    [FingerPosition.Eight] = FingerMask.Eight,
    [FingerPosition.Nine] = FingerMask.Nine,
};

Your code then becomes type-safe in this manner:

private FingerMask getFingerMask(FingerPosition fingerPosition)
{
    FingerMask fingerMask;

    if (_FingerMap.TryGetValue(fingerPosition, out fingerMask))
    {
        return fingerMask;
    }

    return FingerMask.Unknown;
}

You can then cast that result to int if you really need it somewhere else as that.

Leave a Reply

Your email address will not be published. Required fields are marked *