Как привести неподписанный int в uint64

Я хотел бы конвертировать unsigned int в uint64 внутри функции C. uint64 определен в пакете R int64.

РЕДАКТИРОВАТЬ

Этот вопрос касается преобразования из типа данных C unsigned int в тип данных языка uint64 R.

"Пакет int64 был разработан таким образом, что 64-битные целочисленные векторы представлены с использованием только структур данных R, т. е. данные не представлены в виде внешних указателей на некоторый объект C++. Вместо этого каждое 64-битное целое число представляется в виде пары обычных 32-битных целых чисел, каждый из них несет половину битов лежащего в основе 64-разрядного целого числа. Это было сделано по выбору, чтобы 64-разрядные целочисленные векторы можно было сериализовать и использовать в качестве столбцов кадра данных ".

1 ответ

Целое число без знака требуется, чтобы иметь возможность хранить значения по крайней мере в диапазоне 0-65536. Int64_t (это портативная версия, из <stdint.h>) сможет хранить значения между - (2 63 -1) и 2 63. Здесь есть проблема, заключающаяся в том, что unsigned int может иметь длину 64 бита и может представлять значения вне диапазона int64_t (см. §5.2.4.2.1 p1 стандарта C и раздел ниже).

Вот что говорит стандарт:

6.3.1.3 Целые числа со знаком и без знака

  1. Когда значение с целочисленным типом преобразуется в другой целочисленный тип, отличный от _Bool, если значение может быть представлено новым типом, оно не изменяется.
  2. В противном случае, если новый тип является беззнаковым, значение преобразуется путем многократного добавления или вычитания на единицу больше, чем максимальное значение, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне нового типа. 60)
  3. В противном случае новый тип подписывается, и значение не может быть представлено в нем; либо результат определяется реализацией, либо определяется сигнал реализации.

60) Правила описывают арифметику математического значения, а не значения данного типа выражения.


Игнорирование определяемого реализацией сигнала, соответствующего вычислительному исключению, является неопределенным поведением.

В случае конверсии без подписи в подпись, я предлагаю определить ваше поведение явно. Насыщение является самым простым: когда значение int без знака больше INT64_MAX, преобразование приведет к INT64_MAX. Это выглядит примерно так x > INT64_MAX : INT64_MAX ? x, Упаковка в стиле LIA (например, unsigned int x = UINT_MAX; ++x == 0) возможно для int64_t из-за гарантии того, что int64_t не будет содержать отступов, но для обеспечения гарантий переносимости требуется больше работы. Я предлагаю что-то вроде (x & INT64_MIN) > INT64_MAX ? -(x & INT64_MAX) : x & INT64_MAX, если вы можете найти какое-то утверждение, что ваш int64 будет иметь то же представление, что и стандарт C int64_t.

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