值得庆幸的是,C99 标准中引入了
complex
类型修饰符。我不明白的是为什么决定省略对定点算术的支持(具体来说,支持小数类型,如 1.15 {signed} 或 0.32 {unsigned}),而这些类型对于 DSP 编程来说是如此基础?
GCC 是否通过扩展支持这些?
为了解决“GCC 通过扩展支持这些吗”的问题,我们可以引用“使用 GNU 编译器集合”(对于 GCC 版本 4.4.0 - 添加要点以澄清)。 (GCC 4.9.0 URL 等效项是定点 — 使用 GNU 编译器集合 (GCC),但该部分是 6.15 而不是 5.13。)
§5.13 定点类型
作为扩展,GNU C 编译器支持 N1169 中定义的定点类型 ISO/IEC DTR 18037 草案。GCC 中对定点类型的支持将随着 技术报告草案变更。任何目标的调用约定也可能会改变。不是 所有目标都支持定点类型。
定点类型有:
、short _Fract
、_Fract
、long _Fract
、long long _Fract
、unsigned short _Fract
、unsigned _Fract
、unsigned long _Fract
,unsigned long long _Fract
、_Sat short _Fract
、_Sat _Fract
、_Sat long _Fract
、_Sat long long _Fract
、_Sat unsigned short _Fract
、_Sat unsigned _Fract
、_Sat unsigned long _Fract
,_Sat unsigned long long _Fract
、short _Accum
、_Accum
、long _Accum
、long long _Accum
、unsigned short _Accum
、unsigned _Accum
、unsigned long _Accum
,unsigned long long _Accum
、_Sat short _Accum
、_Sat _Accum
、_Sat long _Accum
、_Sat long long _Accum
、_Sat unsigned short _Accum
、_Sat unsigned _Accum
、_Sat unsigned long _Accum
。_Sat unsigned long long _Accum
定点数据值包含小数部分和可选的整数部分。格式为 定点数据会有所不同,具体取决于目标机器。
您可以在此处找到提案草案的文本。
为什么总是一个棘手的问题。 不动点也是一个难以捉摸的概念。 以定点精度分析为主题(即搜索论文、博客等)。 一旦你通过了简单的
typedef fixed_t random_bits
和 FRACTION_SHIFT
(“c”中的一些 Qx.y 实现),你会发现计算必须使用不同的宽度来完成,这是很常见的。 即,需要以扩展精度执行迭代乘法和加法,以保持结果所需的精度。
这与“R”帖子有些相反。 是的,使用整数,但通常您需要找到合适的精度整数。 您经常需要在不同的位分辨率之间进行转换以进行中间计算。 有些域不需要这样做。 因此,定义看似简单的内容可能很难让标准委员会达成一致并提出比
int
更有用的东西。
就像卡尔在评论中所说,定点实际上与整数完全相同。我想该语言可以添加一个功能来在 mult/div 之后为您进行缩放(这与指向 VLA 类型的指针大约处于同一级别:通过为您隐藏缩放算术来清理语法),但考虑到人们想要与定点一起使用的各种尺度和类型混合(例如固定 8.24 乘以固定 24.8,或固定乘以整数),很难很好地涵盖所有内容。
另一个主要问题是目的的区分。定点几乎总是以牺牲正确性为代价来提高速度(因此更容易推出自己的点)。浮点运算(包括 C99 中新的复数支持)适用于当您想要具有已知错误界限的严格结果、防止错误溢出等的安全性时。C99 复数支持为您做的不仅仅是阻止您的复数二项式。它隐藏了确保您的结果不会被极端情况破坏所涉及的所有繁重工作。