int24 - 24位整数数据类型

Oli*_*ops 12 c++

C++中有24Bit原始整数数据类型吗?

如果没有,是否可以创建一个类int24(,uint24)?

它的目的可能是:
*以24位格式操作声音文件
*操纵没有alphachannel的bitmapdata

提前谢谢了

哎呀

Jas*_*ers 20

根据要求,我会使用一个位域.

struct int24{
    unsigned int data : 24;
};
Run Code Online (Sandbox Code Playgroud)

或者,如果分离更容易,只需使用3个字节(字符).

顺便说一下,你在问题中提到的两个用例一般都使用32位整数.在音频处理的情况下,你通常会转换为32位整数(或浮点数,最好是为了防止你用固定点或整数数学得到的溢出情况)加载音频块,因为你不会有整个文件一次在内存中.

对于图像数据,人们只是倾向于使用32位整数并且一起忽略alpha 8 alpha位,或者如果你正在处理紧密排列的格式,你可能最好只是将它们作为char-pointers操作,因为你'将所有通道分开.无论如何,这将是一次性能/内存权衡,因为写一个int通常比三个chars分别快; 但是它需要多25%的内存.

像这样的打包结构是特定于编译器的.但是,在Visual Studio中,您将执行以下操作以使结构正好为24位.

#pragma pack(push, 1)
struct int24{
    unsigned int data : 24;
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)

  • 在大多数情况下,它仍然会被填充到32位. (4认同)
  • 我对这个答案感到很兴奋,但它并没有在 VS2017 上打包。sizeof(int24) == 4。 (2认同)

Goz*_*Goz 14

我这样写是为了帮助我进行音频处理.它不是最快但它对我有用:)

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;
    }

    /***********************************************/
    /***********************************************/
};
Run Code Online (Sandbox Code Playgroud)

  • @Goz:我会加入特殊的逻辑,如果 32 位值为负,则存储的 24 位值始终为负。`INT24_MIN` 是 0xff800000。因此,`INT24_MIN-1` 是`0xff7fffff`,存储为`0x7fffff`,_然后设置“负”位_。然后是`-xFFFFFF`,即-1。由于我没有这样做是为了积极,而且这是违反直觉的,我已经删除了它:http://coliru.stacked-crooked.com/a/eac40bbbb3898348 (2认同)

Nic*_*las 6

使用小于整数(32或64位,取决于您的体系结构)的任何东西都不理想.较小数据类型(简短等)的所有CPU操作都是使用整数运算完成的.必须完成与CPU之间的转换,从而减慢应用程序的速度(即使它只是一点点).

我的建议:将它们存储为32(或64位)整数,以提高整体速度.当需要进行I/O时,您必须自己进行转换.

至于操作音频数据,有许多库可以为您处理I/O - 除非您想开始学习如何存储PCM等 - 以及其他DSP功能.我建议使用其中一个库.

  • 这应该是公认的答案。不是因为我们有相同的名字或任何东西。 (2认同)

ren*_*que 5

我知道我迟到了十年,但是您对位集解决方案有何看法?

class i24
{
    std::bitset<24> m_value;

public:
    constexpr i24(int value) noexcept: m_value {static_cast<unsigned long long>(value)} {}

    operator int() const
    {
        constexpr std::uint32_t negative_mask = (0xff << 24);
        return (m_value[23] ? negative_mask : 0) | m_value.to_ulong();
    }
};
Run Code Online (Sandbox Code Playgroud)