C ++中有24Bit原始整数数据类型吗?
如果没有,是否可以创建一个类int24(,uint24)?
它的目的可能是:
*以24位格式操作声音文件
*操纵没有alphachannel的bitmapdata
非常感谢提前
糟糕
答案 0 :(得分:18)
根据要求,我会使用位域。
struct int24{
unsigned int data : 24;
};
或者,如果分离更容易,只需使用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)
答案 1 :(得分: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;
}
/***********************************************/
/***********************************************/
};
答案 2 :(得分:6)
使用小于整数的任何内容(32位或64位,具体取决于您的体系结构)并不理想。较小数据类型(简短等)的所有CPU操作都是使用整数运算完成的。必须完成与CPU之间的转换,从而减慢应用程序的速度(即使它只是一点点)。
我的建议:将它们存储为32位(或64位)整数,以提高整体速度。当需要进行I / O时,您必须自己进行转换。
就操纵音频数据而言,有许多库可供您处理I / O - 除非您想开始学习如何存储PCM等 - 以及其他DSP功能。我建议使用其中一个库。
答案 3 :(得分:1)
我知道我迟到了十年,但您如何看待 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();
}
};
答案 4 :(得分:0)
不 - 你真正能做的就是:
typedef int32_t int24_t;
有助于使代码/意图更具可读性/显着性,但不会对范围或存储空间施加任何限制。
答案 5 :(得分:0)
最好的方法是创建一个 Int24 类并像原始类型一样使用它。 它会像:
Int24.h
#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;
}
您可以从 my GitHub link 下载 Int24 和 Int48 类。 还有一个例子告诉你如何使用它。