В C++ существует ли целое число на 128 битов?

Я должен сохранить UUID 128 битов длиной в переменной. В C++ существует ли 128-разрядный тип данных? Мне не нужны арифметические операции, я просто хочу легко сохранить и считать значение очень быстро.

Новая возможность от C++ 11 была бы прекрасна, также.

59
задан 26 August 2013 в 12:30

2 ответа

Нет никакого 128-разрядного целого числа в Visual C++, потому что соглашение о вызовах Microsoft только позволяет возвращаться из 2 32-разрядных значений в паре RAX:EAX. Подарки постоянная головная боль, потому что то, когда Вы умножаете два целых числа вместе с результатом, является целым числом с двумя словами. Большая часть поддержки машин загрузки-и-хранилища, работающей с двумя ЦП целые числа, размера слова, но работающий с 4 требуют взлома программного обеспечения, таким образом, 32-разрядный ЦП не может обработать 128-разрядные целые числа и 8-разрядные и 16-разрядные центральные процессоры, не может сделать 64-разрядных целых чисел без довольно дорогостоящего взлома программного обеспечения. 64-разрядные центральные процессоры могут и регулярно работать с 128-разрядным, потому что при умножении двух 64-разрядных целых чисел, Вы получаете 128-разрядное целое число, таким образом, версия 4.6 GCC действительно поддерживает 128-разрядные целые числа. Это дарит проблеме с написанием портативного кода, потому что необходимо сделать ужасный взлом, куда Вы возвращаете одно 64-разрядное слово в регистре возврата, и Вы передаете другой в использовании ссылки. Например, для печати числа с плавающей запятой быстро с Grisu, мы используем 128-разрядное неподписанное умножение следующим образом:

#include <cstdint>
#if defined(_MSC_VER) && defined(_M_AMD64)
#define USING_VISUAL_CPP_X64 1
#include <intrin.h>
#include <intrin0.h>
#pragma intrinsic(_umul128)
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#define USING_GCC 1
#if defined(__x86_64__)
#define COMPILER_SUPPORTS_128_BIT_INTEGERS 1
#endif
#endif

#if USING_VISUAL_CPP_X64
    UI8 h;
    UI8 l = _umul128(f, rhs_f, &h);
    if (l & (UI8(1) << 63))  // rounding
      h++;
    return TBinary(h, e + rhs_e + 64);
#elif USING_GCC
    UIH p = static_cast<UIH>(f) * static_cast<UIH>(rhs_f);
    UI8 h = p >> 64;
    UI8 l = static_cast<UI8>(p);
    if (l & (UI8(1) << 63))  // rounding
      h++;
    return TBinary(h, e + rhs_e + 64);
#else
    const UI8 M32 = 0xFFFFFFFF;
    const UI8 a = f >> 32;
    const UI8 b = f & M32;
    const UI8 c = rhs_f >> 32;
    const UI8 d = rhs_f & M32;
    const UI8 ac = a * c;
    const UI8 bc = b * c;
    const UI8 ad = a * d;
    const UI8 bd = b * d;
    UI8 tmp = (bd >> 32) + (ad & M32) + (bc & M32);
    tmp += 1U << 31;  /// mult_round
    return TBinary(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs_e + 64);
#endif
  }
3
ответ дан 1 November 2019 в 12:04

Я рекомендовал бы использовать std::bitset<128> (можно всегда делать что-то как using UUID = std::bitset<128>;). Это будет, вероятно, иметь подобное расположение памяти к пользовательской структуре предложенным в других ответах, но Вы не должны будете определять свои собственные операторы сравнения, хешировать и т.д.

0
ответ дан 1 November 2019 в 12:04

Другие вопросы по тегам:

Похожие вопросы: