본문 바로가기
Utils

C#, 64비트 초과 비트연산자용 구조체 ShiftComparer

by Client. DJ 2022. 7. 4.
반응형

비트 연산이 필요한 경우

이해를 위한 글: C#, Enum 'Flags' Technic

대형 비트 연산

비트 연산을 하는 과정에서 64비트 길이를 초과하는 경우가 있었는데, 이를 위해 전용 구조체를 만들었습니다.

Add()로 등록하고, Remove()로 삭제할 수 있습니다.

내가 등록한 값이 존재하는지 여부는 IsExist()로 확인 할 수 있습니다.

스크립트

1. 자료형 int 버전

매번 연산을 하여, 연산에 대한 비용이 있습니다.

using System;

public struct ShiftComparer
{
    private static int DIVIND = 32;
    private int[] array;
    private int length;

    public static ShiftComparer Init(int length = 1)
    {
        ShiftComparer shiftComparer;
        shiftComparer.length = (int)Math.Ceiling((float)length / DIVIND);
        shiftComparer.array = new int[length];
        return shiftComparer;
    }

    public void Add(int shift)
    {
        int index = shift / DIVIND;
        if (index < array.Length)
        {
            shift -= index * DIVIND;
            array[index] |= 1 << shift;
        }
    }

    public void Remove(int shift)
    {
        int index = shift / DIVIND;
        if (index < array.Length)
        {
            shift -= index * DIVIND;
            array[index] &= ~1 << shift;
        }
    }

    public bool IsExist(int shift)
    {
        int index = shift / DIVIND;
        if (index < array.Length)
        {
            shift -= index * DIVIND;
            return (array[index] & (1 << shift)) != 0;
        }
        return false;
    }

    public void Clear() => array = new int[length];
}

2. 자료형 bool 버전

int 버전보다 직관적이지만, 배열 공간 하나마다 포인터 메모리 (4byte ~ 8byte)를 할당하니 메모리 측면에서는 int 버전보다 비효율적입니다.

public struct ShiftComparer
{
    private bool[] array;
    private int length;

    public static ShiftComparer Init(int length = 32)
    {
        ShiftComparer shiftComparer;
        shiftComparer.length = length;
        shiftComparer.array = new bool[length];
        return shiftComparer;
    }

    public void Add(int index) => array[index] = true;

    public void Remove(int index) => array[index] = false;

    public bool IsExist(int index)
    {
        if (index < length)
            return array[index];
        return false;
    }

    public void Clear() => array = new bool[length];
}

예제

ShiftComparer checks = ShiftComparer.Init();
checks.Add(1);                           // 1번째 추가
Console.WriteLine(checks.IsExist(1));    // 1번째 존재 여부 확인 ==> True
Console.WriteLine(checks.IsExist(2));    // 2번째 존재 여부 확인 ==> False
checks.Remove(1);                        // 1번째 제거
Console.WriteLine(checks.IsExist(1));    // 1번째 존재 여부 확인 ==> False

마치며

간단하게 비교를 위한 구조체가 필요하여 작성하였습니다. Collection을 사용하면서 존재 여부 확인을 위해 Exists(또는 Contains)를 사용하여 비교하고 값을 확인하는 과정들의 비용이 쓸데없이 거대하여, 비트 연산을 사용하였습니다. 유용하게 사용하세요.😉

반응형

댓글