1

32 비트 부동 소수점을 24 비트 정규화 값으로 변환하는 방법을 알려주십시오. 내가 시도하는 것이입니다 (단위 * (1 < < 24)하지만, 작동하지 않는 것.이. 감사합니다 저를 도와주세요.이 작동하지 않습니다 물론C/C++ - 32 비트 부동 소수점 값을 24 비트 정규화 된 고정 소수점 값으로 변환합니까?

+0

정확히 '24 비트 정규화 값 '이란 무엇을 의미합니까? – hivert

+0

24 비트 정규화 부호없는 정수 – user1128265

+0

그래서 float에 정수가 있다고 가정합니까? 'f = 3.14159265359' 일 때 예상 답변은 무엇입니까? – hivert

답변

0

(1 < < 24) 너무 큰 이 다른 방법을 넣어 정확히 1하여 저장하는 0을 대표 할 수있는 24 비트 숫자를 위해., 1 << 2425 비트 수.

대신 (units * ((1 << 24) - 1))을 고려 사실이다.

        (1 << 24) - 10을 나타낼 수에서 시작 부호없는 24 비트 정수 최대 값이다. 지금

, 범위의 부동 소수점 수 [ 0.0 - 1.0 실제로는 오버 플로우없이 부호없는 24 비트 고정 소수점 정수에 적합 할 것이다.

0

정규화 된 고정 소수점 표현은 엄밀히 도달 할 수없는 최대 표현 가능 값이 1임을 의미합니다. 따라서 1은 1<<24으로 표시됩니다. Q Formats도 참조하십시오.
예를 들어, Q24는 24 소수 비트, 0 정수 비트 및 부호 없음을 의미합니다. Q24를 관리하기 위해 32 비트 부호없는 정수를 사용하는 경우 계산을 쉽게하기 위해 나머지 8 비트를 사용할 수 있습니다.
부동 소수점 표현에서 부동 소수점 표현으로 변환하기 전에 항상 원래 값의 범위를 정의해야합니다. 예 : 부동 소수점 값 [0, 5)의 범위에서 물리량이므로, 0은 포함하고 5 범위에 포함되지 않는, 그리고 고정 소수점 값이 5

#include <string.h> 
#include <stdio.h> 

float length_flp = 4.5;  // Units: meters. Range: [0,5) 
float time_flp = 1.2;  // Seconds. Range: [0,2) 
float speed_flp = 1.2;  // m/sec. Range: [0,2.5) 
unsigned uint32_t length_fixp; // Meters. Representation: Q24 = 24 bit normalized to MAX_LENGTH=5 
unsigned uint32_t time_fixp;  // Seconds. Representation: Q24 = 24 bit normalized to MAX_TIME=2 
unsigned uint32_t speed_fixp; // m/sec. Repr: Q24 = 24 bit normalized to MAX_SPEED=(MAX_LENGTH/MAX_TIME)=2.5 

void main(void) 
{ 
    printf("length_flp=%f m\n", length_flp); 
    printf("time_flp=%f sec\n", time_flp); 
    printf("speed_flp=%f m/sec\n\n", length_flp/time_flp); 

    length_fixp = (length_flp/5) * (1 << 24); 
    time_fixp = (time_flp/2) * (1 << 24); 
    speed_fixp = (length_fixp/(time_fixp >> 12)) << 12; 

    printf("length_fixp=%d m\n", length_fixp); 
    printf("time_fixp=%d sec\n", time_fixp); 
    printf("speed_fixp = %d msec [fixed-point] = %f msec\n", speed_fixp, (float)speed_fixp/(1 << 24) * 2.5); 
} 

이점도로 정규화 정규화 된 표현 사이의 연산은 정규화 된 값을 반환한다는 것입니다. 그런데 오버 플로우를 방지하고 정밀도를 저장하기 위해 각 연산 (나누기, 곱하기 등)에 대한 일반 함수를 정의해야합니다. 작은 트릭을 사용하여 speed_fixp을 계산했습니다. 출력은

length_flp=4.500000 m 
time_flp=1.200000 sec 
speed_flp=3.750000 m/sec 

length_fixp = 15099494 m [fixed-point] 
time_fixp = 10066330 sec [fixed-point] 
speed_fixp = 25169920 msec [fixed-point] = 3.750610 msec 
+0

'x * (1 << 24)'는 중복되어'(x) << 24'가 될 수 있습니다.이것이 8시 24 분 또는 40시 24 분 형식인지 또는 16 비트 임베디드 시스템에서 오버 플로우할지 여부의 모호성도 있습니다. 'uint32_t' 또는'uint64_t'와 같은 특정 타입을 사용해야하고 특정 변수가 정규화되기 전에 * 사용하거나 double/float으로 값 비싼 변환을 사용하는 명시 적으로 명료하게 (semantic'typedef uint32_t uint_fixed_8_24_t') 사용해야합니다. (참고 : [doom m_fixed.c] (http://doomwiki.org/wiki/Doom_source_code_files), 현재의 코딩 표준으로는 거의 맞지 않습니다.)주의 : C는 ints와 double을 기본값으로 사용합니다. – Barry

+0

부동 소수점 왼쪽 피연산자 때문에'x << 24'를 사용할 수 없습니다. 고정 소수점 유형에 대한 자세한 내용을 추가했지만 문제는 명확하게 24 비트 정규화 값에 대해 이야기하고 있습니다. 플랫폼 독립 유형의 사용법은 절대적으로 옳습니다. – omegatre

관련 문제