int24 - Интегральный тип данных на 24 бита

в C++ существует ли примитивный интегральный тип данных на 24 бита?

Если бы нет ни одного, было бы возможно создать класс int24 (uint24)?

это - цель, мог быть:
* управляющий звуковыми файлами в формате на 24 бита
* управляющий bitmapdata без альфа-канала

заранее большое спасибо

Ой

12
задан OlimilOops 21 April 2010 в 12:16
поделиться

4 ответа

Я написал это, чтобы помочь мне с обработкой звука. Это не самый быстрый, но у меня работает :)

const int INT24_MAX = 8388607;

class Int24
{
protected:
    unsigned char m_Internal[3];
public:
    Int24()
    {
    }

    Int24( const int val )
    {
        *this   = val;
    }

    Int24( const Int24& val )
    {
        *this   = val;
    }

    operator int() const
    {
        if ( m_Internal[2] & 0x80 ) // Is this a negative?  Then we need to siingn extend.
        {
            return (0xff << 24) | (m_Internal[2] << 16) | (m_Internal[1] << 8) | (m_Internal[0] << 0);
        }
        else
        {
            return (m_Internal[2] << 16) | (m_Internal[1] << 8) | (m_Internal[0] << 0);
        }
    }

    operator float() const
    {
        return (float)this->operator int();
    }

    Int24& operator =( const Int24& input )
    {
        m_Internal[0]   = input.m_Internal[0];
        m_Internal[1]   = input.m_Internal[1];
        m_Internal[2]   = input.m_Internal[2];

        return *this;
    }

    Int24& operator =( const int input )
    {
        m_Internal[0]   = ((unsigned char*)&input)[0];
        m_Internal[1]   = ((unsigned char*)&input)[1];
        m_Internal[2]   = ((unsigned char*)&input)[2];

        return *this;
    }

    /***********************************************/

    Int24 operator +( const Int24& val ) const
    {
        return Int24( (int)*this + (int)val );
    }

    Int24 operator -( const Int24& val ) const
    {
        return Int24( (int)*this - (int)val );
    }

    Int24 operator *( const Int24& val ) const
    {
        return Int24( (int)*this * (int)val );
    }

    Int24 operator /( const Int24& val ) const
    {
        return Int24( (int)*this / (int)val );
    }

    /***********************************************/

    Int24 operator +( const int val ) const
    {
        return Int24( (int)*this + val );
    }

    Int24 operator -( const int val ) const
    {
        return Int24( (int)*this - val );
    }

    Int24 operator *( const int val ) const
    {
        return Int24( (int)*this * val );
    }

    Int24 operator /( const int val ) const
    {
        return Int24( (int)*this / val );
    }

    /***********************************************/
    /***********************************************/


    Int24& operator +=( const Int24& val )
    {
        *this   = *this + val;
        return *this;
    }

    Int24& operator -=( const Int24& val )
    {
        *this   = *this - val;
        return *this;
    }

    Int24& operator *=( const Int24& val )
    {
        *this   = *this * val;
        return *this;
    }

    Int24& operator /=( const Int24& val )
    {
        *this   = *this / val;
        return *this;
    }

    /***********************************************/

    Int24& operator +=( const int val )
    {
        *this   = *this + val;
        return *this;
    }

    Int24& operator -=( const int val )
    {
        *this   = *this - val;
        return *this;
    }

    Int24& operator *=( const int val )
    {
        *this   = *this * val;
        return *this;
    }

    Int24& operator /=( const int val )
    {
        *this   = *this / val;
        return *this;
    }

    /***********************************************/
    /***********************************************/

    Int24 operator >>( const int val ) const
    {
        return Int24( (int)*this >> val );
    }

    Int24 operator <<( const int val ) const
    {
        return Int24( (int)*this << val );
    }

    /***********************************************/

    Int24& operator >>=( const int val )
    {
        *this = *this >> val;
        return *this;
    }

    Int24& operator <<=( const int val )
    {
        *this = *this << val;
        return *this;
    }

    /***********************************************/
    /***********************************************/

    operator bool() const
    {
        return (int)*this != 0;
    }

    bool operator !() const
    {
        return !((int)*this);
    }

    Int24 operator -()
    {
        return Int24( -(int)*this );
    }

    /***********************************************/
    /***********************************************/

    bool operator ==( const Int24& val ) const
    {
        return (int)*this == (int)val;
    }

    bool operator !=( const Int24& val ) const
    {
        return (int)*this != (int)val;
    }

    bool operator >=( const Int24& val ) const
    {
        return (int)*this >= (int)val;
    }

    bool operator <=( const Int24& val ) const
    {
        return (int)*this <= (int)val;
    }

    bool operator >( const Int24& val ) const
    {
        return (int)*this > (int)val;
    }

    bool operator <( const Int24& val ) const
    {
        return (int)*this < (int)val;
    }

    /***********************************************/

    bool operator ==( const int val ) const
    {
        return (int)*this == val;
    }

    bool operator !=( const int val ) const
    {
        return (int)*this != val;
    }

    bool operator >=( const int val ) const
    {
        return (int)*this >= val;
    }

    bool operator <=( const int val ) const
    {
        return (int)*this <= val;
    }

    bool operator >( const int val ) const
    {
        return ((int)*this) > val;
    }

    bool operator <( const int val ) const
    {
        return (int)*this < val;
    }

    /***********************************************/
    /***********************************************/
};
14
ответ дан 2 December 2019 в 03:43
поделиться

В зависимости от требований я бы использовал для этого битовое поле.

struct int24{
    unsigned int data : 24;
};

Или, если разделение проще, просто используйте 3 байта (символа).

Кстати, в обоих случаях использования, которые вы упомянули в вопросе, обычно используются 32-битные целые числа. В случае обработки звука вы обычно конвертируете в 32-битные целые числа (или числа с плавающей запятой, предпочтительно, чтобы предотвратить ситуации переполнения, которые могут возникнуть с фиксированной точкой или целочисленной математикой) при загрузке фрагментов звука, потому что у вас не будет сразу весь файл в памяти.

Для данных изображения люди просто склонны использовать 32-битные целые числа и игнорировать альфа-8-битные альфа-биты вместе, или, если вы имеете дело с плотно упакованным форматом, вам, вероятно, лучше просто манипулировать ими как указателями на символы потому что у вас все каналы будут раздельными. В любом случае это будет компромисс между производительностью и памятью, потому что запись одного int обычно выполняется быстрее, чем три символа по отдельности; однако потребуется на 25% больше памяти.

Подобные структуры упаковки зависят от компилятора. Однако в Visual Studio вы должны сделать следующее, чтобы структура была ровно 24 бита.

#pragma pack(push, 1)
struct int24{
    unsigned int data : 24;
};
#pragma pack(pop)
20
ответ дан 2 December 2019 в 03:43
поделиться

Нет - все, что вы действительно можете сделать, это:

typedef int32_t int24_t;

, что помогает сделать код / ​​намерение более читаемым / очевидным, но не налагает никаких ограничений на диапазон или пространство для хранения.

0
ответ дан 2 December 2019 в 03:43
поделиться

Работа с числами, меньшими целого числа (32 или 64 бит в зависимости от вашей архитектуры), не идеальна. Все операции ЦП с меньшими типами данных (короткие и т. Д.) Выполняются с использованием целочисленной арифметики. Преобразование в ЦП и обратно должно выполняться, что замедляет работу вашего приложения (даже если это совсем немного).

Мой совет: сохраняйте их как 32 (или 64-битные) целые числа, чтобы повысить общую скорость. Когда придет время выполнять ввод-вывод, вам придется выполнить преобразование самостоятельно.

Что касается управления аудиоданными, существует множество доступных библиотек, которые заботятся о вводе-выводе за вас - если вы не хотите начать изучать, как хранятся PCM и т. Д., - а также о других функциях DSP. Я бы посоветовал использовать одну из многих существующих библиотек.

6
ответ дан 2 December 2019 в 03:43
поделиться
Другие вопросы по тегам:

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