我从解压缩的数据中填充了char data[len]
,该数据是从二进制文件中读取的。
我知道data
只能是这些类型:char, uchar, short, ushort, int, uint, float, double
我知道确切需要表示的位数(elesize = {8, 16, 32, 64}
)。
我只是想遍历数据列表,比如找到max()
,min()
或给定数字的出现次数。我想这样做而不需要为内存空间问题创建另一个数组。
我已经提出了以下内容,但对len == 34560000
所以我想知道是否有人采用'单线'或更有效的方式(C或C ++)。
char data[len];
double mymax = -std::numeric_limits<double>::max()
for (size_t i=0; i<len; i += elesize)
{
double x;
char *r = data+i;
if (elementtype == "char")
x = static_cast<double>(*r);
else if (elementtype == "uchar")
x = static_cast<double>(*((unsigned char *)r));
else if (elementtype == "short")
x = static_cast<double>(*((int16_t *)r));
else if (elementtype == "ushort")
x = static_cast<double>(*((uint16_t *)r));
else if (elementtype == "int")
x = static_cast<double>(*((int32_t *)r));
else if (elementtype == "uint")
x = static_cast<double>(*((uint32_t *)r));
else if (elementtype == "float")
x = static_cast<double>(*((float *)r));
else if (elementtype == "double")
x = *((double *)r);
if (x > mymax)
mymax = x;
}
答案 0 :(得分:1)
模板应该做得很好:
#include <algorithm>
template <typename T>
T read_and_advance(const unsigned char * & p)
{
T x;
unsigned char * const px = reinterpret_cast<unsigned char *>(&x);
std::copy(p, p + sizeof(T), px);
P += sizeof(T);
return x;
}
用法:
const unsigned char * p = the_data;
unsigned int max = 0;
while (p != the_data + data_length)
{
max = std::max(max, read_and_advance<unsigned int>(p));
}
废弃这个,我原本认为这个问题是针对C的。
<子> 子>
这是一个宏:
#define READ_TYPE(T, buf, res) do { memcpy(&res, buf, sizeof(T)); buf += sizeof(T); } while (false)
用法:
int max = 0;
unsigned char * p = data;
while (true)
{
unsigned int res;
READ_TYPE(unsigned int, p, res);
if (res > max) max = res;
}
但是,您并没有真正指定类型。在C ++中,这可以更优雅地完成。
或者你可以把它全部包装在一起:
#define READ_TYPE_AND_MAX(T, buf, max) \
do { T x; memcpy(&x, buf, sizeof(T)); \
buf += sizeof(T); \
if (max < x) max = x; \
} while (false)
// Usage:
unsigned int max = 0;
unsigned char * p = data;
while (true) { READ_TYPE_AND_MAX(unsigned int, p, max); }
答案 1 :(得分:0)
鉴于elementtype
是循环不变的,您最好只在for
之外进行一次比较。顺便说一下,我希望elementtype
类型为std::string
或者与字符串文字进行有意义的比较。
最终,我会编写一个模板函数来执行整个处理循环,然后根据elementtype
使用适当的模板参数调用它。
答案 2 :(得分:0)
将条件代码放在循环外部,因此循环运行得很快。尝试这样的事情:
char data[len];
double mymax = -std::numeric_limits<double>::max()
double x;
if (elementtype == "char") {
for (size_t i=0; i<len; i += elesize) {
char *r = data+i;
x = static_cast<double>(*r);
if (x > mymax) mymax = x;
}
}else if (elementtype == "uchar") {
for (size_t i=0; i<len; i += elesize) {
char *r = data+i;
x = static_cast<double>(*((unsigned char *)r));
if (x > mymax) mymax = x;
}
}else if (elementtype == "short")
..etc..etc
答案 3 :(得分:0)
正如其他人所说,你应该只检查一次类型。然后你应该调用适当的子函数,只处理一种类型。当元素类型不是double时,你也不应该转换为double来与my_max进行比较。否则你将不必要地转换成双倍并与双打进行比较。如果elementtype是uint,那么你永远不应该将任何东西转换为double,只需与同样也是uint的my_max var进行比较。