我想要一个128位整数,因为我想存储两个64位数的乘法结果。在gcc 4.4及以上版本中有没有这样的东西?
128位整数类型仅在64位目标上可用,因此即使您已检测到最近的GCC版本,也需要检查可用性。从理论上讲,gcc可以在机器上支持TI模式整数,它需要4x 32位寄存器来保存一个,但我认为它没有任何情况。
GCC 4.6及更高版本的__int128
/ unsigned __int128
定义为内置类型。使用
#ifdef __SIZEOF_INT128__
检测它。
GCC 4.1及更高版本在__int128_t
中定义__uint128_t
和<stdint.h>
。在最近的编译器中,这可能是根据__int128
来定义的。 (如果你想使用#include <stdint.h>
名称而不是__int128_t
,你仍然需要__int128
。)
我测试了on the Godbolt compiler explorer的第一个版本的编译器来支持这3个东西(在x86-64上)。 Godbolt只能回到gcc4.1,ICC13和clang3.0,所以我用<= 4.1表示实际的第一个支持可能更早。
legacy recommended(?) | One way of detecting support
__uint128_t | [unsigned] __int128 | #ifdef __SIZEOF_INT128__
gcc <= 4.1 | 4.6 | 4.6
clang <= 3.0 | 3.1 | 3.3
ICC <= 13 | <= 13 | 16. (Godbolt doesn't have 14 or 15)
如果编译为像ARM这样的32位架构,或者使用-m32
编译x86,即使是最新版本的任何编译器也不支持128位整数类型。所以你需要在使用之前检测支持,如果没有它你的代码可以完全工作。
我知道检测它的唯一直接CPP宏是__SIZEOF_INT128__
,但不幸的是一些旧的编译器版本支持它而没有定义它。 (而且__uint128_t
没有宏,只有gcc4.6风格的unsigned __int128
)。 How to know if __uint128_t is defined
有些人仍在RHEL(RedHat Enterprise Linux)或类似的旧系统上使用古老的编译器版本,如gcc4.4。如果您关心那些过时的gcc版本,您可能想要坚持使用__uint128_t
。并且可能根据sizeof(int_fast32_t)
检测64位,由于某种原因,在某些64位ISA上为8。但不是像x32或ILP32 AArch64这样的ILP32 ISA,所以如果没有定义sizeof(void*)
,也许只需检查__SIZEOF_INT128__
。
可能有一些64位的ISA,其中gcc没有定义__int128
,或者甚至可能是gcc确定__int128
的一些32位ISA,但我不知道。
正如对此处另一个答案的评论所指出的那样,GCC内部结构是整数TI模式。 (Tetra-integer = qxxswpoi的4倍宽度,而DImode =双倍宽度与SImode =普通int
。)作为int
,支持128位整数模式(TImode)的目标支持the GCC manual points out。
__int128
随机事实:ICC19 typedef unsigned uint128_t __attribute__ ((mode (TI)));
定义:
-E -dM
测试功能是:
#define __GLIBCXX_TYPE_INT_N_0 __int128
#define __GLIBCXX_BITSIZE_INT_N_0 128
支持它的编译器都有效地编译它
#include <stdint.h>
#define uint128_t __uint128_t
//#define uint128_t unsigned __int128
uint128_t mul64(uint64_t a, uint64_t b) {
return (uint128_t)a * b;
}
啊,大整数不是C的强项。
GCC确实有一个 mov rax, rdi
mul rsi
ret # return in RDX:RAX
/ unsigned __int128
类型,从版本4.something开始(这里不确定)。然而,我似乎记得在那之前有一个__int128
def。
这些仅适用于64位目标。
(编者注:这个答案曾经声称gcc定义了__int128_t
和uint128_t
。我在Godbolt编译器浏览器上测试的版本都没有定义那些类型而没有引导int128_t
,从gcc4.1到8.2,或clang或ICC。)
您可以使用处理任意或大精度值的库,例如__
。