C / C ++ - 将32位浮点值转换为24位标准化定点值?

时间:2013-07-17 17:53:38

标签: c floating-point normalization fixed-point floating-point-conversion

请告诉我如何将32位浮点数转换为24位标准化值?我尝试的是(单位*(1 <&lt;&lt; 24),但似乎没有工作。请帮助我。谢谢。

2 个答案:

答案 0 :(得分:0)

当然它不起作用,(1 <&lt; 24)对于能够代表 0 存储的24位数字来说太大了,完全 1 。换句话说,1 << 24实际上是 25位 数字。

请考虑(units * ((1 << 24) - 1))

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

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

答案 1 :(得分:0)

规范化的定点表示,意味着最大可表示值(不是严格可达的)是1.因此1由1<<24表示。另见Q Formats 例如,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