1

请让我知道如何将 32 位浮点数转换为 24 位标准化值?我尝试的是 (units * (1 <<24) 但似乎不起作用。请帮我解决这个问题。谢谢。

4

2 回答 2

0

当然它不起作用, (1 << 24) 对于能够表示0的 24 位数字来说太大而无法存储1。换句话说,1 << 24实际上是一个25 位的数字。

(units * ((1 << 24) - 1))改为考虑。

    (1 << 24) - 1是从0开始的无符号 24 位整数可以表示的最大值。

现在,[ 0.0 - 1.0 ] 范围内的浮点数实际上适合无符号 24 位定点整数而不会溢出。

于 2013-12-23T20:40:00.623 回答
0

归一化的定点表示,意味着最大可表示的值,不是严格可达的,是 1。所以 1 由 表示1<<24。另请参阅Q 格式
例如 Q24 表示 24 个小数位,0 个整数位,无符号。如果使用 32 位无符号整数来管理 Q24,则剩余的 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
于 2013-12-31T09:29:43.660 回答