我正在寻找一种通常可以理解的符号来定义定点数表示法。
该符号应该能够定义二次幂因子(使用小数位)和通用因子(有时我被迫使用它,但效率较低)。并且还应该定义一个可选的偏移量。
我已经知道一些可能的符号,但它们似乎都受限于特定的应用程序。
例如 Simulink表示法完全符合我的需要,但它只在 Simulink 世界中为人所知。此外,fixdt() 函数的重载用法不太可读。
TI 定义了一个非常紧凑的 Q Formats ,但符号是隐含的,并且它不管理通用因子(即不是二次方)。
ASAM使用具有二阶分子和分母多项式的通用 6 系数有理函数 ( COMPU_METHOD )。很普通,但不是那么友好。
另见 Wikipedia讨论。
问题仅与符号有关(与表示效率或定点操作无关)。所以这是一个代码可读性、可维护性和可测试性的问题。
最佳答案
啊,是的。有好的naming annotations 绝对重要不要引入定点运算错误。我使用 Q 表示法的显式版本来处理
通过附加 _Q<M>_<N>
在 M 和 N 之间进行任何划分到变量的名称。这也使得包括签名成为可能。对此没有运行时性能损失。示例:
uint8_t length_Q2_6; // unsigned, 2 bit integer, 6 bit fraction
int32_t sensor_calibration_Q10_21; // signed (1 bit), 10 bit integer, 21 bit fraction.
/*
* Calculations with the bc program (with '-l' argument):
*
* sqrt(3)
* 1.73205080756887729352
*
* obase=16
* sqrt(3)
* 1.BB67AE8584CAA73B0
*/
const uint32_t SQRT_3_Q7_25 = 1 << 25 | 0xBB67AE85U >> 7; /* Unsigned shift super important here! */
如果有人没有完全理解为什么这样的注释非常重要, 您能看出以下两个示例中是否存在错误吗?
示例 1:
speed_fraction = fix32_udiv(25, speed_percent << 25, 100 << 25);
squared_speed = fix32_umul(25, speed_fraction, speed_fraction);
tmp1 = fix32_umul(25, squared_speed, SQRT_3);
tmp2 = fix32_umul(12, tmp1 >> (25-12), motor_volt << 12);
示例 2:
speed_fraction_Q7_25 = fix32_udiv(25, speed_percent << 25, 100 << 25);
squared_speed_Q7_25 = fix32_umul(25, speed_fraction_Q7_25, speed_fraction_Q7_25);
tmp1_Q7_25 = fix32_umul(25, squared_speed_Q7_25, SQRT_3_Q1_31);
tmp2_Q20_12 = fix32_umul(12, tmp1_Q7_25 >> (25-12), motor_volt << 12);
想象一下,如果一个文件包含 #define SQRT_3 (1 << 25 | 0xBB67AE85U >> 7)
另一个文件包含 #define SQRT_3 (1 << 31 | 0xBB67AE85U >> 1)
并且代码在这些文件之间移动。例如 1 这很可能会被忽视并引入示例 2 中存在的错误,这是故意完成的,意外完成的可能性为零。
关于c - 定点表示的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22422557/