gcc中有128位整数吗?

时间:2013-04-18 16:24:22

标签: c gcc x86-64

我想要128位整数,因为我想存储两个64位数的乘法结果。在gcc 4.4及以上版本中有没有这样的东西?

3 个答案:

答案 0 :(得分:30)

啊,大整数不是C的强项。

GCC确实有unsigned __int128 / __int128类型,从版本4.something开始(这里不确定)。然而,我似乎记得在此之前有__int128_t def。

这些仅适用于64位目标。

(编者注:这个答案曾经声称gcc定义了uint128_tint128_t。我在Godbolt编译器资源管理器上测试的所有版本都没有定义那些没有前导__的类型, gcc4.1到8.2,或clang或ICC。)

答案 1 :(得分:11)

您可以使用处理任意或大精度值的库,例如GNU MP Bignum Library

答案 2 :(得分:10)

128位整数类型仅在64位目标上可用,因此,即使您已经检测到最新的GCC版本,也需要检查其可用性。理论上,gcc 可以在需要4个32位寄存器来保存一个寄存器的机器上支持TImode整数,但是我认为在任何情况下它都不会。


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)

如果您为32位体系结构(例如ARM或带有-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__

可能有些gcc没有定义__int128的64位ISA,甚至有些gcc 确实定义__int128的32位ISA,但是我'什么都不知道。

正如对另一个答案的评论所指出的那样,GCC内部是整数TI模式。 (四整数= int的4倍宽度,而DImode =双倍宽度,而SImode =普通int。)与the GCC manual points out一样,支持__int128的目标也受支持128位整数模式(TImode)。

typedef unsigned uint128_t __attribute__ ((mode (TI)));

随机事实:ICC19 -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;
}

所有支持它的编译器都可以高效地对其进行编译,以

    mov       rax, rdi
    mul       rsi
    ret                          # return in RDX:RAX