Я хочу упаковать/распаковать два 16-битных целых числа со знаком в 32-битное целое число. Тем не менее, я не заставляю его работать.
Любые идеи относительно того, что я могу делать неправильно?
template <typename T>
int read_s16(T& arr, int idx) restrict(amp)
{
return static_cast<int>((arr[idx/2] >> ((idx % 2) * 16)) << 16) >> 16;
}
template<typename T>
void write_s16(T& arr, int idx, int val) restrict(amp)
{
// NOTE: arr is zero initialized
concurrency::atomic_fetch_or(&arr[idx/2], (static_cast<unsigned int>(val) & 0xFFFF) << ((idx % 2) * 16));
}
Возврат/аргументы функции должны быть такими, как я определил. lo и hi записываются из разных потоков (таким образом, atomic_or), и чтение должно возвращать одно 32-битное значение.
Целая 16-битная арифметика не поддерживается на целевой платформе.
Пример:
array<int> ar(1); // Container
write_s16(ar, 0, -16);
write_s16(ar, 1, 5);
assert(read_s16(ar, 0) == -16);
assert(read_s16(ar, 1) == 5);
Ответ 2 · рейтинг 3 · Christian Stieber
Это кажется слишком сложным, и там есть странные операции.
Обычно вы просто делаете это так:
int32_t Pack(int16_t a, int16_t b)
{
return (int32_t)((((uint32_t)a)<<16)+(uint32_t)b);
}
int16_t UnpackA(int32_t x)
{
return (int16_t)(((uint32_t)x)>>16);
}
int16_t UnpackB(int32_t x)
{
return (int16_t)(((uint32_t)x)&0xffff);
}
Обратите внимание, что я использовал типы с явными битовыми размерами, чтобы проиллюстрировать, что происходит. Я также позволил себе предположить, что вам нужно "целое число", а не "целое число без знака".
Ответ 3 · рейтинг 2 · Jens Agby
Код ниже отлично работает для меня в MSVC. Как видите, в принципе он такой же, как ваш код.
Может ли проблема заключаться в том, что вы забыли инициализировать содержимое массива нулем? Как ваша платформа обрабатывает отрицательные числа и приведение к беззнаковому целому?
template <typename T>
int read_s16(T& arr, int idx)
{
return static_cast<int>((arr[idx/2] >> ((idx % 2) * 16)) << 16) >> 16;
}
template<typename T>
void write_s16(T& arr, int idx, int val)
{
// NOTE: arr is zero initialized
arr[idx/2] |= (static_cast<unsigned int>(val) & 0xFFFF) << ((idx % 2) * 16);
}
int main()
{
int ar[2] = { 0,0 }; // container
write_s16<int [2]>(ar, 0, -16);
write_s16<int [2]>(ar, 1, 5);
assert(read_s16<int [2]>(ar, 0) == -16);
assert(read_s16<int [2]>(ar, 1) == 5);
return 0;
}