C++中有24位基本整型数据类型吗?如果没有,是否可以创建一个类int24(,uint24)?其目的可能是:
ncgqoxb01#
根据需要,我将使用位域。
struct int24{ unsigned int data : 24;};
struct int24{
unsigned int data : 24;
};
或者,如果分离更容易,则仅使用3个字节(字符)。顺便说一句,你在问题中提到的两个用例通常都使用32位整数。在音频处理的情况下,你通常会转换为32位整数(或浮点数,最好是,以防止溢出的情况下,你会得到与定点或整数数学),当加载块的音频,因为你不会有整个文件在内存中一次。对于图像数据,人们倾向于使用32位整数,而忽略alpha 8位,或者如果你要处理一个紧密压缩的格式,你可能更好地把它们作为字符指针来处理,因为你会把所有的通道分开。这将是一个性能/内存的权衡,因为写一个int通常比分别写三个字符快;但是它将占用多25%内存。像这样打包结构体是编译器特定的。但是,在Visual Studio中,您可以执行以下操作使结构体正好为24位。
#pragma pack(push, 1)struct int24{ unsigned int data : 24;};#pragma pack(pop)
#pragma pack(push, 1)
#pragma pack(pop)
6ie5vjzr2#
我写这个是为了帮助我进行音频操作。它不是最快的,但对我很有效:)
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; } /***********************************************/ /***********************************************/};
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 )
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];
/***********************************************/
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;
Int24& operator -=( const Int24& val )
*this = *this - val;
Int24& operator *=( const Int24& val )
*this = *this * val;
Int24& operator /=( const Int24& val )
*this = *this / val;
Int24& operator +=( const int val )
Int24& operator -=( const int val )
Int24& operator *=( const int val )
Int24& operator /=( const 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 )
*this = *this >> val;
Int24& operator <<=( const int val )
*this = *this << val;
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;
acruukt93#
处理任何小于整数(32位或64位,取决于您的体系结构)的数据都是不理想的。所有较小数据类型(短整型等)的CPU操作都是使用整数运算完成的。必须完成与CPU的转换,这会降低应用程序的速度(即使只是一点点)。我的建议是:将它们存储为32位(或64位)整数以提高整体速度。当需要进行I/O时,您必须自己进行转换。至于操作音频数据,有许多库可以为您处理I/O-除非您想开始学习PCM等是如何存储的-以及其他DSP函数。我建议使用其中的一个库。
a2mppw5e4#
我知道我晚了十年,但你觉得比特集解决方案怎么样?
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(); }};
class i24
std::bitset<24> m_value;
constexpr i24(int value) noexcept: m_value {static_cast<unsigned long long>(value)} {}
constexpr std::uint32_t negative_mask = (0xff << 24);
return (m_value[23] ? negative_mask : 0) | m_value.to_ulong();
lyr7nygr5#
不-您真正能做的是:
typedef int32_t int24_t;
这有助于使代码/意图更可读/更明显,但不会对范围或存储空间施加任何限制。
z4bn682m6#
最好的方法是创建一个Int24类,并像原始类型一样使用它。Int24.h
#ifndef INT24_H#define INT24_Hclass 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
#ifndef INT24_H
#define INT24_H
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;}
#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 |= this->mBytes[0];
addValue = value.mBytes[2];
addValue <<= 8;
addValue |= value.mBytes[1];
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;
void Int24::operator=(unsigned long value)
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;
Int24 Int24::operator++(int)
Int24 temp = (*this);
++(*this);
return temp;
Int24 &Int24::operator--()
(*this) = (*this).value() - 1;
Int24 Int24::operator--(int)
--(*this);
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 |= this->mBytes[0];
你可以从my GitHub link下载Int24和Int48类,这里还有一个例子告诉你如何使用它。
6条答案
按热度按时间ncgqoxb01#
根据需要,我将使用位域。
或者,如果分离更容易,则仅使用3个字节(字符)。
顺便说一句,你在问题中提到的两个用例通常都使用32位整数。在音频处理的情况下,你通常会转换为32位整数(或浮点数,最好是,以防止溢出的情况下,你会得到与定点或整数数学),当加载块的音频,因为你不会有整个文件在内存中一次。
对于图像数据,人们倾向于使用32位整数,而忽略alpha 8位,或者如果你要处理一个紧密压缩的格式,你可能更好地把它们作为字符指针来处理,因为你会把所有的通道分开。这将是一个性能/内存的权衡,因为写一个int通常比分别写三个字符快;但是它将占用多25%内存。
像这样打包结构体是编译器特定的。但是,在Visual Studio中,您可以执行以下操作使结构体正好为24位。
6ie5vjzr2#
我写这个是为了帮助我进行音频操作。它不是最快的,但对我很有效:)
acruukt93#
处理任何小于整数(32位或64位,取决于您的体系结构)的数据都是不理想的。所有较小数据类型(短整型等)的CPU操作都是使用整数运算完成的。必须完成与CPU的转换,这会降低应用程序的速度(即使只是一点点)。
我的建议是:将它们存储为32位(或64位)整数以提高整体速度。当需要进行I/O时,您必须自己进行转换。
至于操作音频数据,有许多库可以为您处理I/O-除非您想开始学习PCM等是如何存储的-以及其他DSP函数。我建议使用其中的一个库。
a2mppw5e4#
我知道我晚了十年,但你觉得比特集解决方案怎么样?
lyr7nygr5#
不-您真正能做的是:
这有助于使代码/意图更可读/更明显,但不会对范围或存储空间施加任何限制。
z4bn682m6#
最好的方法是创建一个Int24类,并像原始类型一样使用它。
Int24.h
Int24.cpp
你可以从my GitHub link下载Int24和Int48类,这里还有一个例子告诉你如何使用它。