C++

C++ 20 : 비트 연산

RuuNee 2024. 6. 4. 17:41
반응형

비트연산은 암호화나 게임서버에서 ID(uint64), 기타 알고리즘 문제에서 자주 사용된다.

 

	{
		//전체 구하기
		unsigned int fullPizza = (1 << 20) - 1;

		//추가
		enum { PEPPERONI = 3 };
		unsigned int toppings = 0;
		toppings |= (1 << PEPPERONI); //3번 토핑 추가

		//포함 여부 확인
		bool added = ((toppings & (1 << PEPPERONI)));
		
		//삭제
		toppings &= ~(1 << PEPPERONI);

		//토글
		toppings ^= (1 << PEPPERONI);

		//개수 구하기
		int count = BitCount(toppings);

		//최소 원소 찾기
		//(끝에 붙어있는 0은 몇개인가?)
		//Visual C++ : _BitScanForward(&index, toppings)
		//gcc : __builtin_ctz(toppings);
	}

 

'피자집에서 피자를 주문하는데 0~19개의 토핑이 존재한다. 토핑을 마음대로 추가해서 피자를 주문.'

예를 들어 위와 같은 문제에서 위와 같은 비트 연산 코드를 사용할 수 있다.

 

이런 비트연산에 새로운 함수들이 많이 생겼다.

 

 bit_cast : 새로운 캐스팅SS
 has_single_bit : 어떤 숫자가 2^n 형태인지 (2의 거듭제곱)
 popcount : unsigned int 숫자에서 1의 개수
 bit_ceil : 해당 값보다 작지 않은 (2의 거듭제곱)중 제일 작은 것 (floor < num < ceil)
 bit_floor : 해당 값보다 크지 않은 (2의 거듭제곱)중 제일 큰 것 (floor < num < ceil)
 bit_width : 해당 값을 표현하기 위해 필요한 최소 비트 개수
 rotl : bitwise left-rotation
 rotr : bitwise right-rotation
 countl_zero : 제일 큰 비트부터 시작해서, 연속된 0의 개수
 countl_one : 제일 큰 비트부터 시작해서, 연속된 1의 개수
 countr_zero : 제일 작은 비트부터 시작해서, 연속된 0의 개수
 countr_one : 제일 작은 비트부터 시작해서, 연속된 1의 개수

 

 

	float n1 = 1.0f;
	int n2 = static_cast<int>(n1); //1.0이라는 값을 정수로 변환해서 저장.
	int n3 = bit_cast<int>(n1);  //저장되어있던 숫자 그대로를 정수로 변환.

 

n1
n2
n3

 

 

예제 코드

	std::uint8_t num = 0b00110010;
	cout << boolalpha;

	cout << std::has_single_bit(num) << endl; // false
	cout << popcount(num) << endl; // 3
	cout << std::bitset<8>(std::bit_ceil(num)) << endl; // 0b01000000
	cout << std::bitset<8>(std::bit_floor(num)) << endl; // 
	cout << std::bit_width(5u) << endl; // width(0x000101) = 3
	cout << std::bitset<8>(std::rotl(num, 2)) << endl; // 0b11001000
	cout << std::bitset<8>(std::rotr(num, 2)) << endl; // 0b10001100
	cout << countl_zero(num) << endl; // 2
	cout << countl_one(num) << endl; // 0
	cout << countr_zero(num) << endl; // 1
	cout << countr_one(num) << endl; // 0

 

 


 

 

 

네트워크와 파일 입출력에서 중요한 요소중 하나인 엔디안.

 

	std::endian::native;

	if (std::endian::native == std::endian::big)
	{
		cout << "big endian" << endl;
	}
	else
	{
		cout << "little" << endl;
	}

 

위 코드 처럼 편하게 사용가능하게 바뀌었다.

 

 

 

 

 

 

 

 

반응형