Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어로 부동 소수점 숫자의 세트 비트 개수 구하는 방법

이 문제에서는 하나의 부동 소수점 값이 주어지며, 해당 값의 이진 표현에서 세트 비트(set bit, 즉 1로 설정된 비트)가 몇 개인지 구해야 합니다.

예를 들어 부동 소수점 수가 0.15625라면 세트 비트는 총 6개입니다. 일반적인 C 컴파일러는 단정밀도(single precision) 부동 소수점 방식을 사용하므로, 이 값은 메모리에 다음과 같이 저장됩니다.

C 언어로 부동 소수점 숫자의 세트 비트 개수 구하는 방법

접근 방법

부동 소수점 숫자의 실제 비트 값을 확인하려면 다음 과정을 거칩니다.

1. 해당 숫자의 주소를 포인터 변수에 담습니다.
2. 포인터를 char* 타입으로 캐스팅합니다.
3. float는 보통 4바이트이므로, 각 바이트를 하나씩 순회하며 처리합니다.
4. 각 바이트(문자)에 대해 세트 비트의 개수를 계산하여 모두 더합니다.

여기서 세트 비트를 세는 데 사용되는 것은 브라이언 커니핸(Brian Kernighan) 알고리즘입니다. 이 알고리즘은 n &= (n-1) 연산을 반복하는데, 이 연산은 가장 오른쪽에 있는 1비트를 한 번에 제거하므로 반복 횟수만큼 곧 세트 비트의 개수가 됩니다.

예제 코드

#include <stdio.h>

// 한 바이트(char) 내의 세트 비트 개수를 계산하는 함수
int char_set_bit_count(char number) {
    unsigned int count = 0;
    while (number != 0) {
        number &= (number - 1); // 가장 오른쪽의 1비트 제거
        count++;
    }
    return count;
}

// float 전체의 세트 비트 개수를 계산하는 함수
int count_float_set_bit(float x) {
    // float 크기를 char 크기로 나눠 바이트 수 계산
    unsigned int n = sizeof(float) / sizeof(char);
    int i;
    char *ptr = (char *)&x; // 변수의 주소를 char*로 캐스팅
    int count = 0; // 결과를 저장할 변수

    for (i = 0; i < n; i++) {
        count += char_set_bit_count(*ptr); // 각 바이트의 비트 계산
        ptr++;
    }
    return count;
}

main() {
    float x = 0.15625;
    printf("Binary representation of %f has %u set bits", x, count_float_set_bit(x));
}

실행 결과

Binary representation of 0.156250 has 6 set bits

코드 설명

char_set_bit_count() 함수는 입력받은 바이트 값이 0이 될 때까지 number &= (number - 1) 연산을 반복하면서 세트 비트를 하나씩 제거하고 그 횟수를 셉니다.

count_float_set_bit() 함수는 sizeof(float)/sizeof(char)로 float를 구성하는 바이트 수를 구한 뒤, char*로 캐스팅한 포인터를 이용해 각 바이트를 순차적으로 접근하며 세트 비트를 누적 합산합니다.

이처럼 포인터 캐스팅 기법을 활용하면 부동 소수점 숫자의 내부 비트 표현을 손쉽게 검사할 수 있으며, 이 방법은 double 등 다른 자료형에도 동일하게 응용할 수 있습니다.