C中的字和双字整数
Posted
技术标签:
【中文标题】C中的字和双字整数【英文标题】:Word and Double Word integers in C 【发布时间】:2010-01-10 05:09:59 【问题描述】:我正在尝试在 C 中实现一个简单、中等效率的 bignum 库。我想使用编译它的系统的完整寄存器大小(大概是 32 位或 64 位整数)来存储数字。我的理解是我可以使用 intptr_t 完成此操作。它是否正确?有没有更符合语义的类型,例如 intword_t 之类的?
我还知道,使用 GCC,我可以通过将两个参数向上转换为 64 位整数来轻松地在 32 位机器上进行溢出检测,这将占用两个寄存器并利用 IA31 ADC 之类的指令(带进位相加)。我可以在 64 位机器上做类似的事情吗?有没有我可以向上转换的 128 位类型,如果它们可用,它们将编译以使用这些指令?更好的是,是否有代表两倍寄存器大小的标准类型(如 intdoubleptr_t),因此可以以独立于机器的方式完成?
谢谢!
【问题讨论】:
有什么理由不想使用现有且经过良好测试的库? Mitch:对我来说,这主要是一个练习我的 C 的练习。 在 x86_64 系统上使用 GCC,您可以使用__int128_t
类型进行 128 位整数运算。但是,这不是便携式的。
几年前在 Java 中做了同样的事情,它也不支持 asm 来检查位,它在内部表示为 31 或 63 位比在使用时扩大效率要高得多。 GMP 对“钉子”有实验性支持,这似乎是一种类似的方法。
Pete,我认为您应该将该评论添加为实际答案(添加到“检测溢出”部分)。
【参考方案1】:
有什么理由不使用 size_t 吗? size_t 在 32 位系统上是 4 个字节,在 64 位系统上是 8 个字节,并且可能比使用 WORD_SIZE 更便携(我认为 WORD_SIZE 是 gcc 特定的,不是吗?)
我不知道 64 位系统上的任何 128 位值,这里可能是错误的,但在内核或普通用户应用程序中没有遇到这种类型。
【讨论】:
我从中得到的印象是 intptr_t 比 size_t 更便于移植:***.com/questions/1464174/sizet-vs-intptrt 当然,我不是要存储指针,而是要存储一个整数占用了整个寄存器。 @datkin:您的链接中的问题专门关于存储指针。对于您的情况,size_t
优于 intptr_t
,或者使用 [u]int[_fast]N_t
类型。
我知道这只是一个练习,但便携性有多重要?如果它不重要,那么也许你不关心 size_t。我在#defines 中使用 size_t 时也遇到了问题【参考方案2】:
我强烈建议使用 C99 <stdint.h>
标头。它声明了int32_t
、int64_t
、uint32_t
和uint64_t
,看起来就像你真正想要使用的一样。
编辑:正如 Alok 指出的那样,int_fast32_t
、int_fast64_t
等可能是您想要使用的。您指定的位数应该是数学运算所需的最小值,即计算不会“翻转”。
优化来自这样一个事实,即 CPU 不必浪费周期重新对齐数据、在读取时填充前导位以及在写入时执行读取-修改-写入。事实是,很多处理器(例如最近的 x86s)在 CPU 中都有硬件可以很好地优化这些访问(至少是填充和读取-修改-写入部分),因为它们非常常见并且通常只涉及之间的传输处理器和缓存。
因此,您唯一要做的就是确保访问对齐:获取 sizeof(int_fast32_t)
或其他任何内容,并使用它来确保您的缓冲区指针与其对齐。
事实是,这可能不会带来太大的改进(由于硬件在运行时优化传输),所以编写一些东西并定时它可能是唯一确定的方法。此外,如果您真的对性能非常着迷,您可能需要查看 SSE 或 AltiVec 或您的处理器拥有的任何矢量化技术,因为在进行矢量数学运算时,它们的性能将优于您可以编写的任何可移植的东西。
【讨论】:
问题是我希望在 32 位机器上使用 int32_t 和在 64 位机器上使用 int64_t 存储数字。以下是比使用 intptr_t 类型更好的方法吗?:#if __WORDSIZE == 64 typedef int64_t intword_t #else typedef int32_t intword_t #endif 另外,在 32 位机器上,我总是可以将 int32_t 向上转换为 int64_t 以确保此外,等不会溢出,但是在 64 位机器上,是否有 128 位类型我可以向上转换以避免溢出? C99 定义了int_fast64_t
、int_fast32_t
等。所以也许它们会有用?由于您的目标是实现一个中等效率的库,我会说使用上述之一,然后根据需要进行优化。
我的理解是 int_fastXX_t 类型只是您机器的自然 int 类型的“别名”(除非 XX 大于机器的本机 int 宽度)。因此 int_fast8_t 在 32 位机器上为 32 位,在 64 位机器上为 64 位。这些类型是否提供其他优化或仅此而已?
@datkin,是的:int_fast32_t
实际上可能是 int64_t
。但它们不提供任何其他优化。我之所以提出这个建议是因为您在原始问题中提到了优化。无论如何,由于您只是“尝试”,您应该选择一种类型,然后再进行优化。以上是关于C中的字和双字整数的主要内容,如果未能解决你的问题,请参考以下文章