programing

C에서 uint32_t를 바이너리로 변환하는 중

goodcopy 2022. 11. 6. 13:29
반응형

C에서 uint32_t를 바이너리로 변환하는 중

제가 안고 있는 주요 문제는 C의 2진수 값을 읽는 것입니다.Python과 C#은 이것을 하기 위한 매우 빠르고 쉬운 함수를 가지고 있습니다.C++에서 그것을 하는 방법에 대한 토픽을 찾았습니다.C에서 int를 바이너리로 변환하는 방법에 대한 토픽을 찾았지만, C에서 uint32_t를 바이너리로 변환하는 방법은 찾지 못했습니다.

여기서 하려고 하는 것은 ESP32의 DR_REG_RNG_BASE 주소의 32비트를 비트로 읽는 것입니다(이것은 ESP의 랜덤하드웨어 제너레이터의 랜덤 값이 격납되어 있는 주소입니다).

그래서 내가 그걸 하고 있는 순간:

#define DR_REG_RNG_BASE                        0x3ff75144

void printBitByBit( ){

    // READ_PERI_REG is the ESP32 function to read DR_REG_RNG_BASE
    uint32_t rndval = READ_PERI_REG(DR_REG_RNG_BASE);
    int i;
    for (i = 1; i <= 32; i++){ 
      int mask =  1 << i;
      int masked_n = rndval & mask;
      int thebit = masked_n >> i;   
      Serial.printf("%i", thebit);
    }
    Serial.println("\n");
}

처음에는 잘 되는 줄 알았어요.하지만 사실 이건 완전히 잘못된 이진수 표현에서 벗어나게 해 줍니다.좋은 생각 있어요?

표시된 코드에는 여러 가지 오류/문제가 있습니다.

첫 번째 비트 위치uint32_t(32비트 부호 없는 정수)는 제로 베이스입니다.따라서 코드대로1 ~ 32가 아니라 0 ~ 31에서 실행됩니다.따라서 코드에서는 (효과적으로) 최저 비트(비트 #0)를 무시하고 있습니다.또한 이 명령어를 실행하면1 << i마지막 루프에서 (일 때)i == 32마스크의 값(대부분)은 0입니다(단, 기술적으로 코드 사용으로 부호 있는 정수에 대한 정의되지 않은 동작이지만). 따라서 가장 높은 비트도 드롭됩니다.

둘째, 코드가 가장 낮은 비트를 먼저 인쇄합니다(왼쪽에서 오른쪽으로). 그러나 보통과 같이 가장 높은 비트를 먼저 인쇄해야 합니다.따라서 루프를 실행해 주세요.i31부터 시작하여 0까지 감소합니다.

또한 코드에는 부호 없는 정수형과 부호 있는 정수형이 혼합되어 있습니다.이런 일은 피하는 것이 가장 좋기 때문에 사용하는 것이 좋습니다.uint32_t루프로 사용되는 중간값입니다.

마지막으로(Eric이 코멘트에서 언급한 바와 같이) 부호 없는 정수에서 "bit n"을 추출하는 훨씬 간단한 방법이 있습니다.value >> n & 1.

저는 Arduino 플랫폼에 액세스 할 수 없습니다만, 위의 논의의 요점을 설명하기 위해, 여기 표준 콘솔 모드 C++ 프로그램이 있습니다.이 프로그램은 코드 출력과 앞서 언급한 수정을 적용한 버전을 비교합니다.

#include <iostream>
#include <cstdint>
#include <inttypes.h>

int main()
{
    uint32_t test = 0x84FF0048uL;
    int i;
    // Your code ...
    for (i = 1; i <= 32; i++) {
        int mask = 1 << i;
        int masked_n = test & mask;
        int thebit = masked_n >> i;
        printf("%i", thebit);
    }
    printf("\n");
    // Corrected limits/order/types ...
    for (i = 31; i >= 0; --i) {
        uint32_t mask = (uint32_t)(1) << i;
        uint32_t masked_n = test & mask;
        uint32_t thebit = masked_n >> i;
        printf("%"PRIu32, thebit);
    }
    printf("\n");
    // Better ...
    for (i = 31; i >= 0; --i) {
        printf("%"PRIu32, test >> i & 1);
    }
    printf("\n");
    return 0;
}

출력의 3행(처음 1행은 오답, 마지막 2행은 정답)은 다음과 같습니다.

001001000000000111111110010000-10
10000100111111110000000001001000
10000100111111110000000001001000

주의:

( 생긴 (1)의 "%"PRu32( 「」를 형식 지정자)uint32_t유형, 참조: uint32_t size_t의 printf 형식 지정자를 참조하십시오.

(의 (uint32_t)(1)하면 constant를 지정해도 비트 해집니다.int ★★★★★★★★★★★★★★★★★」unsigned열여섯 살이에요.그렇지 않으면 이러한 경우 정의되지 않은 동작이 발생합니다.

언급URL : https://stackoverflow.com/questions/73594091/converting-uint32-t-to-binary-in-c

반응형