【问题标题】:Converting from float to q7_t in ARM Cortex?在 ARM Cortex 中从浮点数转换为 q7_t?
【发布时间】:2020-05-16 00:16:50
【问题描述】:

我了解 ARM Cortex M4 中使用的小数类型用于最大化 n 位数字的精度,在 q7_t 的情况下它是从 -1 到 1-2^-7 的归一化数字。

但是其使用的典型工作流程是怎样的?是否需要不断地对使用的变量进行规范化和反规范化?

我找到了下一个从单精度浮点数转换为 q7_t 的示例代码,“128”数字在做什么?

float test_float = 3.1416f;
q7_t test_frac = (q7_t)( test_float * 128);

提前谢谢你。

【问题讨论】:

  • 你有反汇编吗?
  • 用于最大化 n 位数字的精度”没有什么意义。它仅用于以 8 位表示 +/-1.0。由于 pi X 128 > 255,代码也没有意义。您关于 128 的问题的答案是它会导致算术溢出 - 不能再多说了。该数据类型旨在供关联的 arm_math.h 库使用,而不是通用算术。

标签: c arm embedded signal-processing microcontroller


【解决方案1】:

因为q7_t类型只有7位来存储小数,所以以128的小数形式存储比较合适。简单来说就是将数字的小数部分分成128个大小相等的块,每个块可以是用整数值0127 表示。

所以整数值0 代表0.0。整数值1 代表0.0078125 (1 / 128.0)。整数值2 代表0.015625 (2 / 128.0)。以此类推。

【讨论】:

  • 那么在转换为q类型之前,是否仍然需要将函数中的浮点变量标准化为特定于应用程序的预定义范围?
【解决方案2】:

Q 格式只是从整数到小数值的缩放。

让我们考虑字节中的位,编号从 0(当位被写出时在右侧)到 7(在左侧)。在常见的二进制表示法中,位 i 表示值 2i。 8位表示的值是设置位表示的值之和,所以01000011代表67(26 + 21 + 20)。

当二进制补码用于支持负数时,最高位,本例中的第 7 位,表示其纯二进制值的负数,因此 -27

在“Q”格式中,这些位的值被移位。在 Q7 格式中,位 i 表示 2i-7,除了最高位的值被取反,因此位 7 为 -27-7支持> = -1。名称也可以写成 Q0.7。从概念上讲,这些数字告诉我们在位中放置“二进制点”(如小数点)以读取表示的值的位置。 Q3.4格式有一个符号位,二进制前三位,二进制后四位,如0100.0011,表示4 + 3/16 = 26−4 + 2 1−4 + 20−4 = 22 + 2−3 + 2−4 = 4 + 1/8 + 1/16 = 4 3/16.

另一种思考方式是,以纯二进制(或二进制补码)格式表示某些 x 的位表示 x/2n 采用 Qm.n 格式。

如果你的编译器有一个完全支持的 q7 类型,你可以只为它分配值而不处理它们的表示方式:q7 x = .25; 将初始化 x 以包含值 1/4 通过放置位 00100000进入它。

从您的示例看来,您可能有一个“自己动手”Q7 类型,它实际上只是一个八位有符号整数。在这种情况下,您必须在表示的值和 Q7 类型之间进行一些转换。给定表示整数 x 的任意八位,它们将表示 Q7 格式中的 x/128,因为在 Q7 格式中,值为 2 的位i 在 Q7 格式中的值为 2i−7

因此,如果您有一些浮点数 f,并且您想将其存储为 Q7 格式,则使用 q7_t x = f * 128;f 调整为整数正常缩放中的相应值。相反,x / 128.f 采用 x 表示的整数值并将其缩放为 Q7 格式中的位表示的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    相关资源
    最近更新 更多