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_tint64_tuint32_tuint64_t,看起来就像你真正想要使用的一样。

编辑:正如 Alok 指出的那样,int_fast32_tint_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_tint_fast32_t 等。所以也许它们会有用?由于您的目标是实现一个中等效率的库,我会说使用上述之一,然后根据需要进行优化。 我的理解是 int_fastXX_t 类型只是您机器的自然 int 类型的“别名”(除非 XX 大于机器的本机 int 宽度)。因此 int_fast8_t 在 32 位机器上为 32 位,在 64 位机器上为 64 位。这些类型是否提供其他优化或仅此而已? @datkin,是的:int_fast32_t 实际上可能是 int64_t。但它们不提供任何其他优化。我之所以提出这个建议是因为您在原始问题中提到了优化。无论如何,由于您只是“尝试”,您应该选择一种类型,然后再进行优化。

以上是关于C中的字和双字整数的主要内容,如果未能解决你的问题,请参考以下文章

为啥Android的button的字和上下边缘的间距那么大

79.C++ 中的字面值常量

2018/10/03-字符串指令(重复指令操作数据缓冲区指令)rep与movx指令-《恶意代码分析实战》

使用浮点数和双精度时,c 中的 -0.0000 是啥?

指针数组 (*A)[] 和双指针 **A 之间的区别

python中,如何去掉字串自带的引号