【问题标题】:Why aren't fixed-point types included in C99?为什么 C99 中不包含定点类型?
【发布时间】:2012-03-27 04:50:34
【问题描述】:

谢天谢地,complex 类型修饰符被引入 C99 标准。我不明白的是为什么决定省略对定点算术的支持(具体来说,支持像 1.15 {signed} 或 0.32 {unsigned} 这样的小数类型),而这些类型对于 DSP 编程如此重要?

GCC 是否通过扩展支持这些?

【问题讨论】:

  • 定点类型和整数一样吧?
  • @CarlNorum:不是真的;它们的比例有点像整数,但是当你将两个数字相乘时,你最终也会改变结果。
  • @CarlNorum - 整数是定点数的子集,其中二进制点位于 lsb 的右侧。通常,您可以将点放在寄存器中的任何位置,但您必须保持算术运算符的一致性。
  • @CarlNorum - 例如,如果您有格式为 1.15 的数字(二进制​​点左侧 1 位,右侧 15 位),则使用整数乘法将得到 2.30 结果。然后,您必须将其左移 1 个位置并截断低 16 位以返回 1.15 格式。
  • 我们大多数人会称之为将结果右移 15 位.. :-)

标签: c gcc c99 fixed-point


【解决方案1】:

它已被讨论/提议(例如,在N938N953)但那些论文只是将其作为扩展提出,而不是对主要标准的补充。这些似乎导致它包含在N1169 中,这是 TR 18037 的草案(“支持嵌入式处理器的扩展”),但这并不完整(并且该草案似乎没有在一段时间)。

我的猜测(虽然这只是一个猜测)是它的工作可能会被放弃(至少是暂时的)以专注于完成 C11。现在是否会恢复它的工作可能取决于周围是否还有人仍然关心。根据那些涵盖更多细节、提供更多支持性证据等的早期论文撰写和提交论文,可能有助于重新启动它(尽管我显然不能保证任何事情)。

【讨论】:

  • 仅供参考,2016 年 4 月,我与 WG14 召集人 David Keaton 取得了联系。他随后针对 TR18037 和 N1169 的状态回复如下:“......目前,我们没有任何计划将 TR 18037 添加到 C 标准中。但是,我们注意到 TR 肯定是在行业中使用,我们计划保持可用。..."
【解决方案2】:

要解决“GCC 是否通过扩展支持这些”问题,我们可以引用“使用 GNU 编译器集合”(对于 GCC 版本 4.4.0 — 添加的要点以澄清)。 (GCC 4.9.0 URL 等效项是 Fixed Point — Using the GNU Compiler Collection (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

定点数据值包含小数部分和可选的整数部分。的格式 定点数据因目标机器而异。

您可以找到提案草案的文本here

【讨论】:

  • 请注意,这被排除在 C11 的标准化之外(也没有包含在 C99 中,但我怀疑它当时是否已经设计好了)。因此,虽然它可能对 OP 实际上有用,但我认为它不能回答为什么不包含它的问题。
  • 但它确实回答了最后一个问题:GCC 是否支持它们?
  • 某种支持,但取决于平台。特别是,GCC 似乎不支持 x86 或 x86_64 的定点类型。
【解决方案3】:

就像卡尔在评论中所说,定点实际上与整数完全相同。我想该语言可以在 mult/div 之后添加一个功能来为您进行缩放(这与指向 VLA 类型的指针大致相同:通过为您隐藏缩放算法来清理语法)但考虑到人们想要与定点一起使用的各种尺度和类型组合(例如,固定 8.24 乘以固定 24.8,或固定乘以整数),真的很难涵盖所有内容。

另一个主要问题是目的的区别。定点几乎总是以牺牲正确性为代价来提高速度(因此,您自己的滚动要容易得多)。浮点运算,包括 C99 中的新复数支持,适用于当您想要具有已知错误界限的严格结果、防止错误溢出等安全性时。C99 复数支持为您做的不仅仅是 FOIL'ing 您的复数二项式。 .它隐藏了确保您的结果不会被极端情况破坏所涉及的所有繁重工作。

【讨论】:

  • 对不起,我在这里不同意。它与整数完全相同。请参阅我对卡尔的评论。您是对的,有许多可能的组合,但在 DSP 领域中,两个占主导地位的是整数和小数(有符号与无符号小数的细微差别 - 1.15 与 0.16)。
  • 在一般意义上,您可能会争辩说这是为了提高速度,但实际上,处理器本身可能只支持这些类型 - 硬件中没有 FP,因此它确实映射了C 代码到底层硬件。此外,FP 并不总是比定点算术更准确。如果您的中间结果的指数相对恒定,那么对于给定的字长,您实际上使用定点算法可以获得更高的精度。
  • 固定点也适用于您希望在您感兴趣的值范围内具有相同绝对精度的情况(经典示例:纬度/经度)。
  • 在我看来,您的论点支持语言包含,而不是反对它。正确处理所有这些转换应该是自动化的,而不是程序员必须担心的事情,因为这就是产生错误的方式!而且,与您所说的相反,只要编译器知道小数和整数部分的宽度,自动化它就相当容易。
  • @Fritz:大小未标准化的定点类型将毫无用处。大小标准化的定点大小可能很好,但应该比包装大小标准化的无符号整数类型具有更低的优先级,这样wrap16_t x=65535; x*=x; 将保证将x 设置为1,而与@ 的大小无关987654323@.
猜你喜欢
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 2016-11-12
  • 2016-03-26
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多