2016-07-29 6 views
-4

Как преобразовать массив int в массив int16_t в C++ или C с низкой стоимостью? Предположим, что все значения в массиве int находятся внутри диапазона int16_t.C++ преобразовать массив int в массив int16_t

Я знаю два варианта:

i. Используйте для цикла, чтобы назначить каждый элемент в массиве int соответствующему элементу в массиве int16_t.

int *a = new int[2]; 
a[0] = 1; 
a[1] = 2; 

int16_t *b = new int16_t[2]; 

for (int i = 0; i < 2; i++) { 
    b[i] = a[i]; 
} 

Но ему нужно сделать копию и накладные расходы.

ii. Использование литого

int16_t* c = reinterpret_cast<int16_t*>(a); 

//1 0 2 0 
for (int i = 0; i < 4; i++) { 
    cout << (int)r[i] << endl; 
} 

Но я не хочу, чтобы те 0.

Есть ли другой способ недорогой передачи Int массива [2], чтобы int16_t массива [2] и сохранить значение?

+1

На современных архитектурах есть большая вероятность, что вы собираетесь усекать ценности. «Int» больше 32-битные или 64-битные (не гарантированные, но, как правило, так), и «int16_t» гарантированно будет 16 бит.Повторная интерпретация указателя не будет тем, что вы хотите, так как вы по существу превращаете 'int' в ** two **' int16_t', предполагая, что 'int' - 32 бита в вашей системе. – Qix

+0

Кроме того, поскольку вы вырезаете ints, вы можете получить неожиданные результаты по архитектуре с большими концами во втором, reinterpret_cast примере –

+0

Да. Но я получаю массив int из других компонентов, хотя я знаю, что значения гарантированно находятся в пределах 16-битного целого числа (int16_t). Таким образом, [i] не будет усечен, если я сделаю b [i] = (int16_t) a [i]. –

ответ

3

Поскольку вы не можете делать какие-либо предположения о размере int (стандарт делает не давать какие-либо заявления о точного размера примитивных типов данных), вы не можете делать любые фантазии трюков с помощью слепков здесь. Ваш пример:

int16_t* c = reinterpret_cast<int16_t*>(a); 

не работает, потому что на системе типа int случается 32 бит долго, поэтому для каждого int вы получите дваint16_t. В вашем случае это так получилось, что все значения в определенном диапазоне, поэтому второй int16_t всегда 0.


Я хотел бы предложить просто скопировать ваши целые числа. Все остальное - преждевременная оптимизация.

+1

Это абсолютный правильный ответ. Побей меня. – Qix

+0

Я знаю, что значения гарантированно находятся в пределах 16-битного целого числа (int16_t или я также могу использовать короткий), хотя они хранятся как 32-битные int. Копирование имеет накладные расходы, а мой компонент требует высокой эффективности. –

+0

Просто невозможно переинтерпретировать данные, если макет памяти не соответствует. Таким образом, вы ничего не можете сделать, кроме копирования. Не пытайтесь оптимизировать перед измерением! Это преждевременная оптимизация. – nshct

-1

Можете ли вы просто избежать копирования и просто использовать массив int1_t6?

Поскольку вы увеличиваете размер элементов массива (возможно, зависит от платформы), вам придется либо скопировать, либо использовать вспомогательную функцию/при каждом доступе. Поскольку значения все еще меньше, вы не получаете ничего из них как int16_t, если вам не нужно изменять значения с помощью других int16_t.

Я думаю, это действительно зависит от того, что вам нужно делать со значениями, когда они являются int16_t.

int16_t getArrVal(const unsigned index){ 
return array[index]; 
} 
0

Поскольку целевая int16_t представлена ​​меньшим числом битов, чем исходный INT (32 бита или более) биты должны быть преобразованы из 32/64 бит до 16 бит. Ваше первое решение правильно, но компиляторы будут предупреждать о назначении меньшему int. С static_cast до int16_t с правой стороны присваивания будет отключено предупреждение.

Да, под преобразованием Я имею в виду копию.

Смежные вопросы