gcc中有128位整数吗? [英] Is there a 128 bit integer in gcc?

查看:46
本文介绍了gcc中有128位整数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个 128 位整数,因为我想存储两个 64 位数字相乘的结果.gcc 4.4 及更高版本中有这样的东西吗?

I want a 128 bit integer because I want to store results of multiplication of two 64 bit numbers. Is there any such thing in gcc 4.4 and above?

推荐答案

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

A 128-bit integer type is only ever available on 64-bit targets, so you need to check for availability even if you have already detected a recent GCC version. In theory gcc could support TImode integers on machines where it would take 4x 32-bit registers to hold one, but I don't think there are any cases where it does.

GCC 4.6 及更高版本将 __int128/unsigned __int128 定义为内置类型. 使用
#ifdef __SIZEOF_INT128__ 来检测它.

GCC 4.6 and later has a __int128 / unsigned __int128 defined as a built-in type. Use
#ifdef __SIZEOF_INT128__ to detect it.

GCC 4.1 及更高版本将 __int128_t__uint128_t 定义为内置类型.(你不需要<代码>的#include< stdint.h> 对于这些,无论是证明上Godbolt .)

GCC 4.1 and later define __int128_t and __uint128_t as built-in types. (You don't need #include <stdint.h> for these, either. Proof on Godbolt.)

我测试了 在 Godbolt 编译器浏览器上 用于支持这三件事的第一版编译器(在 x86-64 上).Godbolt 只回溯到 gcc4.1、ICC13 和 clang3.0,所以我使用 <= 4.1 表示实际的第一次支持可能更早.

I tested on the Godbolt compiler explorer for the first versions of compilers to support each of these 3 things (on x86-64). Godbolt only goes back to gcc4.1, ICC13, and clang3.0, so I've used <= 4.1 to indicate that the actual first support might have been even earlier.

         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 位整数类型.所以你需要在使用之前检测支持,如果没有它你的代码完全可以工作的话.

If you compile for a 32-bit architecture like ARM, or x86 with -m32, no 128-bit integer type is supported with even the newest version of any of these compilers. So you need to detect support before using, if it's possible for your code to work at all without it.

我知道用于检测它的唯一直接 CPP 宏是 __SIZEOF_INT128__,但不幸的是,一些旧的编译器版本支持它而没有定义它.(并且没有 __uint128_t 的宏,只有 gcc4.6 样式的 unsigned __int128).如何知道__uint128_t是否已定义

The only direct CPP macro I'm aware of for detecting it is __SIZEOF_INT128__, but unfortunately some old compiler versions support it without defining it. (And there's no macro for __uint128_t, only the gcc4.6 style unsigned __int128). How to know if __uint128_t is defined

有些人仍然在 RHEL (RedHat Enterprise Linux) 或类似的老旧系统上使用 gcc4.4 等古老的编译器版本.如果你关心过时的 gcc 版本,你可能想坚持使用 __uint128_t.并且可能根据 sizeof(void*) == 8 检测 64 位作为 __SIZEOF_INT128__ 未定义的后备.(我认为 GNU 系统总是有 CHAR_BIT==8).这将对 64 位 ISA(如 x86-64 Linux x32 或 AArch64 ILP32)上的 ILP32 ABI 产生误报,但这对于使用未定义 __SIZEOF_INT128__ 的旧编译器的人来说已经只是一个后备/奖励.

Some people still use ancient compiler versions like gcc4.4 on RHEL (RedHat Enterprise Linux), or similar crusty old systems. If you care about obsolete gcc versions like that, you probably want to stick to __uint128_t. And maybe detect 64-bitness in terms of sizeof(void*) == 8 as a fallback for __SIZEOF_INT128__ no being defined. (I think GNU systems always have CHAR_BIT==8). That will give a false negative on ILP32 ABIs on 64-bit ISAs (like x86-64 Linux x32, or AArch64 ILP32), but this is already just a fallback / bonus for people using old compilers that don't define __SIZEOF_INT128__.

可能有一些 64 位 ISA,其中 gcc 没有定义 __int128,或者甚至可能有一些 32 位 ISA,其中 gcc 定义了 __int128,但我不知道.

There might be some 64-bit ISAs where gcc doesn't define __int128, or maybe even some 32-bit ISAs where gcc does define __int128, but I'm not aware of any.

正如对此处另一个答案的评论所指出的,GCC 内部是整数 TI 模式.(四整数 = int 的 4 倍宽度,DImode = 双倍宽度 vs. SImode = 普通 int.)作为 GCC 手册指出__int128 在支持 128 位整数模式(TImode).

As comments on another answer here point out, the GCC internals are integer TI mode. (Tetra-integer = 4x width of int, vs. DImode = double width vs. SImode = plain int.) As the GCC manual points out, __int128 is supported on targets that support a 128-bit integer mode (TImode).

// __uint128_t is pre-defined equivalently to this
typedef unsigned uint128 __attribute__ ((mode (TI)));

<小时>

随机事实:ICC19 和 g++/clang++ -E -dM 定义:

#define __GLIBCXX_TYPE_INT_N_0 __int128
#define __GLIBCXX_BITSIZE_INT_N_0 128

@MarcGlisse 评论 这就是你告诉 libstdc++ 处理额外整数类型(重载 abs、专门化类型特征等)的方式

@MarcGlisse commented that's the way you tell libstdc++ to handle extra integer types (overload abs, specialize type traits, etc)

icpc 定义了即使使用 -xc (编译为 C,而不是 C++),而 g++ -xc 和 clang++ -xc 没有.但是使用实际的 icc 进行编译(例如,在 Godbolt 下拉菜单中选择 C ​​而不是 C++)并没有定义这个宏.

icpc defines that even with -xc (to compile as C, not C++), while g++ -xc and clang++ -xc don't. But compiling with actual icc (e.g. select C instead of C++ in the Godbolt dropdown) doesn't define this macro.

测试函数是:

#include <stdint.h>   // for uint64_t

#define uint128_t __uint128_t
//#define uint128_t unsigned __int128

uint128_t mul64(uint64_t a, uint64_t b) {
    return (uint128_t)a * b;
}

支持它的编译器都可以有效地编译它,以

compilers that support it all compile it efficiently, to

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

这篇关于gcc中有128位整数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆