C++ int24 - 24 位整数数据类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2682725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:20:18  来源:igfitidea点击:

int24 - 24 bit integral datatype

c++

提问by OlimilOops

is there a 24Bit primitive integral datatype in C++?

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

If there is none, would it be possible to create a class int24 (, uint24 ) ?

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

it's purpose could be:
* manipulating soundfiles in 24 bit format
* manipulating bitmapdata without alphachannel

它的目的可能是:
* 操作 24 位格式的声音文件
* 操作没有 alphachannel 的位图数据

many thanks in advance

提前谢谢了

Oops

哎呀

采纳答案by Goz

I wrote this to help me with audio manipulation. Its not the fastest but it works for me :)

我写这个是为了帮助我处理音频。它不是最快的,但对我有用:)

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

    /***********************************************/
    /***********************************************/
};

回答by Jasper Bekkers

Depending on the requirements I'd use a bitfield for it.

根据要求,我会使用位域。

struct int24{
    unsigned int data : 24;
};

Or, if a separation is easier, just use 3 bytes (chars).

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

Btw, both use cases you mention in the question generally use 32bit integers. In the case of audio processing you'll generally convert to 32 bit ints (or floats, preferably, to prevent overflow situations you'd get with fixed point or integer math) when loading in chunks of audio because you're not going to have the entire file in memory at once.

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

For image data, people just tend to use 32 bit integers and ignore the alpha 8 alpha bits all together, or if you're dealing with a tightly packed format you're probably better of just manipulating them as char-pointers anyway because you'll have all channels separate. It's going to be a performance/memory trade-off anyway because writing one int is generally faster than three chars separately; however it will take 25% more memory.

对于图像数据,人们只是倾向于使用 32 位整数而忽略 alpha 8 alpha 位,或者如果您正在处理紧密压缩的格式,您可能最好将它们作为字符指针进行操作,因为您将所有通道分开。无论如何,这将是性能/内存的权衡,因为写入一个 int 通常比单独写入三个字符快;但是它会多占用 25% 的内存。

Packing structs like this is compiler specific. However, in Visual Studio you'd do the following to make the struct exactly 24 bits.

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

#pragma pack(push, 1)
struct int24{
    unsigned int data : 24;
};
#pragma pack(pop)

回答by Nicolas

Working with anything smaller than an integer (32 or 64 bit depending on your architecture) is not ideal. All CPU operations of the smaller data types (short, etc) are done using integer arithmetic. Conversion to and from the CPU has to be done, slowing your application down (even if it is just a tad).

使用小于整数(32 位或 64 位,取决于您的架构)的任何内容都不理想。较小数据类型(短等)的所有 CPU 操作都使用整数算法完成。必须完成与 CPU 之间的转换,这会降低您的应用程序的速度(即使它只是一点点)。

My advice: Store them as 32 (or 64 bit) integers to improve your overall speed. When it comes time to do I/O, then you'll have to do the conversion yourself.

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

As far as manipulating audio data, there are many libraries available that take care of the I/O for you - unless you want to start learning how PCM, etc are stored - as well as other DSP functions. I would suggest using one of the many libraries out there.

至于处理音频数据,有许多可用的库可以为您处理 I/O - 除非您想开始学习 PCM 等的存储方式 - 以及其他 DSP 功能。我建议使用那里的众多图书馆之一。

回答by Paul R

No - all you can really do is:

不 - 你真正能做的就是:

typedef int32_t int24_t;

which helps to make code/intent more readable/obvious, but doesn't impose any limits on range or storage space.

这有助于使代码/意图更具可读性/明显性,但不会对范围或存储空间施加任何限制。