Re: Special Data Type Declaration and Usage
On Nov 15, 9:30 pm, mrc2...@cox.net (Mike Copeland) wrote:
In article <op.v40apype4vp...@gp.homenet.telecomitalia.it>,
gennaro.prota+Use...@gmail.com says...> On Tue, 15 Nov 2011 22:04:25 +010=
0, Mike Copeland <mrc2...@cox.net> wrote:
I need to declare an enormous array (100,000 members) of a sma=
ll
scalar object, and I want to populate it with default values and chan=
ge
some of them as needed throughout the processing. The range of dis=
tinct
values for each element is 0-15, so I could use a 4 bit "mini-byte"
the common term for a 4-bit quantity is a "nibble"
Is your data sparse? That is, are there many more default values than
other values? If so consider a sparse array. Only store the non-
default values and return default if the lookup fails.
if
something like that existed.
My question is: can I declare a bit structure data type and us=
e it
this way? If that's possible, I don't know how to do so, nor how I=
'd
manipulate the data values in it. Please advise. TIA
there are bit fields but I've never been keen. I normally use explicit
masks and shifts to extract bit fields. Something like this:-
<code>
typedef unsigned char Byte;
typedef unsigned char Nibble;
class NibbleContainer
{
public:
NibbleContainer(size_t size, Nibble default_value = 0);
size_t size() const { return m_size; }
void set (size_t i, Nibble nib);
Nibble get (size_t i) const;
private:
size_t m_size;
std::vector<Byte> m_vec;
};
inline bool is_odd (size_t n) { return n % 2 == 1; }
NibbleContainer::NibbleContainer(size_t size, Nibble default_value):
m_size(size), m_vec ((size + 1) / 2)
{
for (size_t i = 0; i < size; i++)
set (i, default_value);
}
void NibbleContainer::set (size_t i, Nibble nib)
{
assert (i < m_size);
assert (nib < 16);
size_t vec_index = i / 2;
if (is_odd (i))
{
// stick it in the top nibble
nib <<= 4;
m_vec [vec_index] &= 0x0f;
m_vec [vec_index] |= nib;
}
else
{
// stick it in the bottom nibble
m_vec [vec_index] &= 0xf0;
m_vec [vec_index] |= nib;
}
}
Nibble NibbleContainer::get (size_t i) const
{
assert (i < m_size);
size_t vec_index = i / 2;
if (is_odd (i))
// get it from the top nibble
return (m_vec [vec_index] >> 4) & 0x0f;
else
// get it from the bottom nibble
return m_vec [vec_index] & 0x0f;
}
</code>
now that amount of c-like c++ is bound to provoke a reaction...
Are you sure that the array is "enormous"? Using one (whole!) byte per
element it would occupy less than 100KiB.
It's "enormous" to me, as I have many other large data structures =
in
this program, and I have to declare it globally (it's accessed from a
number of subprograms in several source files). My concern is Heap
allocation, inasmuch as there must be _some_ limit as to how much
program data can be declared before the program chokes. I;m using
VS6.0, and I don't know what that limit is.
I was hoping that I could cut down the total size of this data
component and still process it efficiently. It seems not possible...
depends what "efficient" means. How many non-defaults do you have? How
often do they change? How often do you read a value? How often do you
write a value? etc. etc. You need to measure things and get some hard
numebrs.