问题 如何创建128位整数文字


我有一个格式的整数文字 0x75f17d6b3588f843b13dea7c9c324e51。有没有办法避免编译器语法错误“整数文字太大而无法在任何整数类型中表示”?

因为我知道我可以使用这些类型(我正在使用 uint128_t 从EOS库,如果我手动插入它,它的工作原理)。

有没有办法在运行时以某种方式将此字符串直接解析为完全相同的整数?


7590
2017-07-26 12:17


起源

整数文字必须可由某些内置整数类型(通常最多64位)表示,以后您将其分配给某个可以容纳该数字的类型并不重要。 - Baum mit Augen
您是否尝试过将Ls添加到文字中?否则,您可能必须声明自定义文字并自己构造uint128_t。 - Goswin von Brederlow
@GoswinvonBrederlow添加Ls无济于事。 - Baum mit Augen
C的同一个问题: 在C中分配128位整数 - Baum mit Augen
为此宣布自定义文字可能的解决方案? - Bida


答案:


标准不强制要求128位整数文字,因此如果要允许它们,则由实现决定。大多数都没有,因此您需要将其分解为两个64位组件并使用按位运算符组合它们:

__uint128_t num = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;

一个好的编译器应该在编译时执行操作。


7
2017-07-26 12:58



嗨,这看起来很酷,但结果与原版不一样,它得到0x514e329c7cea3db143f888356b7df175 - Bida
@Bida你究竟得到这个价值?如果您在x86 / x64之类的小端机器上运行,则整数类型的字节将以最低有效字节存储。如果按顺序打印字节,您将看到输出中反映的字节。 - dbush
标准没有针对128位整数文字的规则。就标准而言,实现甚至可以给它们类型 int。但是,标准规定的最小值只有64位,而这就是 long long。 - MSalters
@dbush是eos的小尾数,对不起你是对的 - Bida
@MSalters好点。更新以澄清 - dbush


你可以写一个 原始文字运算符 (一种用户定义的文字,因为C ++ 11),用于128位整数。

原始文字运算符只需一个 const char* 作为参数。你可以编写一个函数体来解析字符串。

例如:

// Use __uint128_t for demonstration.
constexpr __uint128_t operator""_uint128_t(const char* x)
{
    __uint128_t y = 0;
    for (int i = 2; x[i] != '\0'; ++i)
    {
        y *= 16ull;
        if ('0' <= x[i] && x[i] <= '9')
            y += x[i] - '0';
        else if ('A' <= x[i] && x[i] <= 'F')
            y += x[i] - 'A' + 10;
        else if ('a' <= x[i] && x[i] <= 'f')
            y += x[i] - 'a' + 10;
    }
    return y;
}

显然,这种实现是有问题的,因为 我懒得开发一个完整的解决方案, 它只支持十六进制,它不检查 0x 它需要C ++ 14轻松的constexpr功能。但它表明您实际上可以将此字符串直接解析为完全相同的整数。

我们来测试一下:

int main()
{
    auto abc = 0x1234567890ABCDEFfedcba0987654321_uint128_t;
    std::uint64_t higher = abc >> 64;
    std::uint64_t lower = abc;
    std::cout << std::hex << higher << ' ' << lower;
}

http://coliru.stacked-crooked.com/a/fec4fc0fd4ff1418


8
2017-07-26 13:35