繁体   English   中英

int24 - 24 位整数数据类型

[英]int24 - 24 bit integral datatype

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

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

它的目的可能是:
* 操作 24 位格式的声音文件
* 在没有 alpha 通道的情况下操作位图数据

提前谢谢了

哎呀

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

struct int24{
    unsigned int data : 24;
};

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

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

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

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

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

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

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

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

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

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

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

我知道我迟到了十年,但是您如何看待 bitset 解决方案?

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

不 - 你真正能做的就是:

typedef int32_t int24_t;

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

最好的方法是创建一个 Int24 类并像原始类型一样使用它。 它会是这样的:

24小时


#ifndef INT24_H
#define INT24_H

class Int24
{
public:
    Int24();
    Int24(unsigned long);

    Int24 operator+ (Int24 value);
    Int24 operator* (int value);
    Int24 operator/ (int value);

    void operator= (unsigned long value);
    void operator= (Int24 value);
    operator int() const;


    // Declare prefix and postfix increment operators.
    Int24 &operator++();       // Prefix increment operator.
    Int24 operator++(int);     // Postfix increment operator.

    // Declare prefix and postfix decrement operators.
    Int24 &operator--();       // Prefix decrement operator.
    Int24 operator--(int);     // Postfix decrement operator.

    unsigned long value() const;

private:
    unsigned char mBytes[3] ;
};

#endif // INT24_H

Int24.cpp


#include "Int24.h"

Int24::Int24()
{
    mBytes[0] = 0;
    mBytes[1] = 0;
    mBytes[2] = 0;
}

Int24::Int24(unsigned long value)
{
    mBytes[0] = ( value         & 0xff);
    mBytes[1] = ((value >>  8)  & 0xff);
    mBytes[2] = ((value >> 16 ) & 0xff);
}

Int24 Int24::operator+(Int24 value)
{
    Int24 retVal;
    unsigned long myValue;
    unsigned long addValue;

     myValue = this->mBytes[2];
     myValue <<= 8;
     myValue |= this->mBytes[1];
     myValue <<= 8;
     myValue |= this->mBytes[0];

     addValue = value.mBytes[2];
     addValue <<= 8;
     addValue |= value.mBytes[1];
     addValue <<= 8;
     addValue |= value.mBytes[0];

     myValue += addValue;

     retVal = myValue;

     return retVal;
}

Int24 Int24::operator*(int value)
{
    (*this) = (*this).value() * value;
    return (*this);
}

Int24 Int24::operator/(int value)
{
    (*this) = (*this).value() / value;
    return (*this);
}

void Int24::operator=(unsigned long value)
{
    mBytes[0] = ( value         & 0xff);
    mBytes[1] = ((value >>  8)  & 0xff);
    mBytes[2] = ((value >> 16 ) & 0xff);
}

void Int24::operator=(Int24 value)
{
    mBytes[0] = value.mBytes[0];
    mBytes[1] = value.mBytes[1];
    mBytes[2] = value.mBytes[2];
}

Int24 &Int24::operator++()
{
    (*this) = (*this).value() + 1;
    return *this;
}

Int24 Int24::operator++(int)
{
    Int24 temp = (*this);
    ++(*this);
    return temp;
}

Int24 &Int24::operator--()
{
    (*this) = (*this).value() - 1;
    return *this;
}

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

Int24::operator int() const
{
    return value();
}

unsigned long Int24::value() const
{
    unsigned long retVal;

    retVal = this->mBytes[2];
    retVal <<= 8;
    retVal |= this->mBytes[1];
    retVal <<= 8;
    retVal |= this->mBytes[0];

    return retVal;
}

您可以从我的 GitHub 链接下载 Int24 和 Int48 类。 还有一个示例向您展示了如何使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM