gcc中有128位整数吗?

Met*_*est 39 c gcc x86-64 bigint 128-bit

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

sle*_*ica 32

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

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

这些仅适用于64位目标.

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

  • 尝试`typedef int really_long __attribute __((mode(TI)));`.它已经工作了很长时间(在原生64位架构上). (4认同)
  • gcc-4.1 -m64及更高版本支持开箱即用的__uint128_t,它们还支持以下typedef:typedef unsigned uint128_t __attribute__((mode(TI)));`。 (2认同)

Pet*_*des 19

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。)

在Godbolt编译器资源管理器上测试了第一个支持这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)
Run Code Online (Sandbox Code Playgroud)

如果您针对诸如ARM或x86之类的32位体系结构进行编译,-m32则即使是这些编译器中的任何最新版本也不支持128位整数类型。 因此,如果没有它,代码完全可以工作,则需要在使用前检测支持。

我知道唯一可以检测到的直接CPP宏是__SIZEOF_INT128__,但是不幸的是,一些旧的编译器版本在不定义它的情况下就支持它。(并且没有__uint128_tgcc4.6样式的宏unsigned __int128)。 如何知道__uint128_t是否已定义

某些人仍在使用RHEL(RedHat Enterprise Linux)上的gcc4.4等古老的编译器版本,或类似的硬壳旧系统。如果您关心这样的过时gcc版本,则可能要坚持使用__uint128_t。也许sizeof(int_fast32_t)出于某种原因,在某些64位ISA上可以检测到64 位的错误。但不是在x32或ILP32 AArch64之类的ILP32 ISA上,因此也许只是检查sizeof(void*)是否__SIZEOF_INT128__未定义。

gcc __int128可能没有定义一些64位ISA,甚至gcc 确实定义了一些32位ISA __int128,但是我不知道。

正如这里对另一个答案的评论所指出的那样,GCC内部是整数TI模式。(四整数=的4倍宽度int,而DImode =两倍宽度而SImode =普通int。)正如GCC手册指出的那样__int128支持128位整数模式(TImode)的目标支持。

typedef unsigned uint128_t __attribute__ ((mode (TI)));
Run Code Online (Sandbox Code Playgroud)

随机事实:ICC19 -E -dM定义:

#define __GLIBCXX_TYPE_INT_N_0 __int128
#define __GLIBCXX_BITSIZE_INT_N_0 128
Run Code Online (Sandbox Code Playgroud)

测试功能为:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

    mov       rax, rdi
    mul       rsi
    ret                          # return in RDX:RAX
Run Code Online (Sandbox Code Playgroud)

  • `unsigned __int128`-最坏的部分是*。通常(特别是使用div / mod算术例程),我们知道商将适合64位结果,但是C运行时无法假定它。我写了一个参考'modexp'(64位基数,指数,模数),使用__int128 ... ...与使用64位内在函数的版本[倒数除法](https://gmplib.org/~tege /division-paper.pdf)等,以实现* 18x *的加速!3x或4x是可以理解的,但是请记住,总是会产生调用开销,并且[u] int128函数无法做出我们可以做到的算法断言! (2认同)

Ree*_*sey 11

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

  • 在现代的64位计算机上,可以非常高效地执行128位算术运算。任意精度算术的开销将在很大程度上抵消现代64位CPU的好处。我很惊讶如此懒惰的答案获得了如此多的赞誉。 (7认同)
  • @CrazyCasta 拥有一个仅适用于 128 位类型的任意精度库太浪费了,而且开销太大了。像 [Boost.Multi precision 或 calccrypto/uint128_t](/sf/answers/1968251071/) 这样的固定宽度库将会更小、更快 (3认同)