gcc中有128位整数吗?

问题描述 投票:30回答:3

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

c gcc x86-64
3个回答
10
投票

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;
}

30
投票

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

GCC确实有一个 mov rax, rdi mul rsi ret # return in RDX:RAX / unsigned __int128类型,从版本4.something开始(这里不确定)。然而,我似乎记得在那之前有一个__int128 def。

这些仅适用于64位目标。

(编者注:这个答案曾经声称gcc定义了__int128_tuint128_t。我在Godbolt编译器浏览器上测试的版本都没有定义那些类型而没有引导int128_t,从gcc4.1到8.2,或clang或ICC。)


11
投票

您可以使用处理任意或大精度值的库,例如__

© www.soinside.com 2019 - 2024. All rights reserved.