implemented conversion for 16bit floats
This commit is contained in:
60
src/endian.hpp
Normal file
60
src/endian.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef MY_LITTLE_ENDIAN
|
||||
#define MY_LITTLE_ENDIAN
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define IS_BIG_ENDIAN (*(uint16_t*)"\0\xff" < 0x100)
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
class endian
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
// endianness
|
||||
bool little_endian_;
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
endian()
|
||||
{
|
||||
// check endianness on machine
|
||||
little_endian_ = get_endian();
|
||||
}
|
||||
|
||||
// provide information about little versus big endian architecture
|
||||
bool get_endian()
|
||||
{
|
||||
// declare short (16 bit) integer representing "1"
|
||||
short int wd = 0x001;
|
||||
|
||||
// get byte pattern of integer
|
||||
uint8_t *pwd = (uint8_t*)(&wd);
|
||||
|
||||
//for ( int i = 0; i < 2; i ++ ) std::cout<<std::hex<<(int)pwd[i]<<" ";
|
||||
//std::cout<<"\n";
|
||||
|
||||
// check if byte pattern is 0x 0001 or 0x 0100
|
||||
return ((int)pwd[0] == 1 ? true : false);
|
||||
}
|
||||
|
||||
// retrieve information
|
||||
bool little_endian()
|
||||
{
|
||||
return little_endian_?true:false;
|
||||
}
|
||||
|
||||
bool big_endian()
|
||||
{
|
||||
return little_endian_?false:true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
100
src/half_precision_floating_point.hpp
Normal file
100
src/half_precision_floating_point.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef HALF_PRECISION_FLOATING_POINT
|
||||
#define HALF_PRECISION_FLOATING_POINT
|
||||
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
#include "endian.hpp"
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
class half_precision_floating_point
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
// size of half precision floating point number in bits
|
||||
int size_ = 16;
|
||||
|
||||
// construction of the number (binary16) according to IEEE 754-2008 standard
|
||||
std::bitset<1> sign_;
|
||||
std::bitset<5> expo_;
|
||||
std::bitset<10> frac_;
|
||||
|
||||
// endianness of machine/architecture
|
||||
bool little_endian_;
|
||||
|
||||
// number as single-precision floating point number
|
||||
float num_;
|
||||
|
||||
// array of bytes representing the number
|
||||
std::vector<uint8_t> numbytes_;
|
||||
|
||||
public:
|
||||
|
||||
// constructors
|
||||
half_precision_floating_point(std::vector<uint8_t> numbytes) :
|
||||
numbytes_(numbytes)
|
||||
{
|
||||
assert( numbytes_.size() == 2 );
|
||||
endian endi;
|
||||
little_endian_ = endi.little_endian();
|
||||
assert( little_endian_ && "just don't work on big endian machines!" );
|
||||
}
|
||||
|
||||
half_precision_floating_point(float num) :
|
||||
num_(num)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// destructor
|
||||
~half_precision_floating_point()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// assignment operator
|
||||
half_precision_floating_point& operator=(const half_precision_floating_point& other)
|
||||
{
|
||||
if ( this != &other )
|
||||
{
|
||||
size_ = other.size_;
|
||||
sign_ = other.sign_;
|
||||
expo_ = other.expo_;
|
||||
frac_ = other.frac_;
|
||||
little_endian_ = other.little_endian_;
|
||||
num_ = other.num_;
|
||||
numbytes_ = other.numbytes_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// convert byte pattern to number
|
||||
void convert_to_float()
|
||||
{
|
||||
// declare a single precision floating point number
|
||||
// float myfloat = 0.0;
|
||||
|
||||
if ( little_endian_ )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// convert floating point number to bytes
|
||||
void convert_to_byte()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
36
src/main.cpp
36
src/main.cpp
@@ -9,13 +9,13 @@
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// path of filename provided ?
|
||||
assert( argc > 1 && "please provide a filename and path" );
|
||||
assert( argc > 2 && "please provide a filename and path for input and output" );
|
||||
|
||||
std::cout<<"number of CLI-arguments: "<<argc<<"\n";
|
||||
for ( int i = 0; i < argc; i++ ) std::cout<<std::setw(5)<<i<<": "<<argv[i]<<"\n";
|
||||
|
||||
// check number of CLI arguments
|
||||
assert( argc == 2 );
|
||||
assert( argc == 3 );
|
||||
|
||||
// get name/path of file from CLI argument
|
||||
std::string rawfile(argv[1]);
|
||||
@@ -23,9 +23,12 @@ int main(int argc, char* argv[])
|
||||
// declare instance of "raw_eater"
|
||||
raw_eater eatraw(rawfile);
|
||||
|
||||
eatraw.show_markers();
|
||||
//eatraw.show_markers();
|
||||
|
||||
// determine position of markers in buffer and read data
|
||||
eatraw.find_markers();
|
||||
|
||||
std::cout<<"\n";
|
||||
std::map<std::string,std::vector<unsigned char>> marks = eatraw.get_markers();
|
||||
for ( auto mrk: marks )
|
||||
{
|
||||
@@ -39,13 +42,32 @@ int main(int argc, char* argv[])
|
||||
std::cout<<"\n";
|
||||
}
|
||||
|
||||
eatraw.convert_data();
|
||||
// convert unsigned char data in buffer to desired data type
|
||||
//eatraw.convert_data();
|
||||
eatraw.convert_data_16_bit_float();
|
||||
|
||||
std::vector<double> mydata = eatraw.get_data();
|
||||
std::cout<<"\n"<<mydata.size()<<"\n\n";
|
||||
// get array of encoded data
|
||||
std::vector<double> maindata = eatraw.get_data();
|
||||
std::cout<<"\nsize of data array: "<<maindata.size()<<"\n\n";
|
||||
//for ( unsigned long int i = 0; i < 10; i++ ) std::cout<<mydata[i]<<"\n";
|
||||
|
||||
eatraw.write_data(std::string("csv/myfile.csv"));
|
||||
// write data in csv-file
|
||||
eatraw.write_data(std::string(argv[2]));
|
||||
|
||||
float ab = -0.75;
|
||||
std::cout<<ab<<"\n";
|
||||
uint8_t* pab = reinterpret_cast<uint8_t*>(&ab);
|
||||
for ( int i = 0; i < (int)sizeof(float); i++ ) std::cout<<std::hex<<(int)pab[i]<<std::dec<<" ";
|
||||
std::cout<<"\n";
|
||||
|
||||
uint8_t sc = 0x4f;
|
||||
std::bitset<8> bssc(sc);
|
||||
for ( int i = 0; i < 8; i++ ) std::cout<<bssc[i]<<" ";
|
||||
std::cout<<"\n";
|
||||
std::cout<<std::hex<<bssc.to_ulong()<<"\n\n";
|
||||
|
||||
endian endi;
|
||||
std::cout<<(endi.little_endian()?"little endian":"big endian")<<"\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
109
src/raweat.hpp
109
src/raweat.hpp
@@ -1,5 +1,8 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef RAW_EATER
|
||||
#define RAW_EATER
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -8,6 +11,9 @@
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
|
||||
#include "half_precision_floating_point.hpp"
|
||||
#include "endian.hpp"
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
class raw_eater
|
||||
@@ -40,6 +46,9 @@ private:
|
||||
// data sections corresponding to markers
|
||||
std::map<std::string,std::vector<unsigned char>> datasec_;
|
||||
|
||||
// length of data array
|
||||
unsigned long int datsize_;
|
||||
|
||||
// TODO preliminary: for now, we assume 32/64 bit ? floats in all data
|
||||
std::vector<double> datmes_;
|
||||
|
||||
@@ -61,17 +70,6 @@ public:
|
||||
(std::istreambuf_iterator<char>()));
|
||||
rawdata_ = rawdata;
|
||||
|
||||
// show size of buffer
|
||||
std::cout<<"size of buffer "<<rawdata_.size()<<"\n";
|
||||
|
||||
// show excerpt from buffer
|
||||
int ista = 0, iend = 128;
|
||||
for ( int i= ista; i < iend; i++ )
|
||||
{
|
||||
std::cout<<std::hex<<(int)rawdata_[i]<<" ";
|
||||
if ( (i+1)%16 == 0 ) std::cout<<"\n";
|
||||
}
|
||||
std::cout<<"\n";
|
||||
}
|
||||
|
||||
// destructor
|
||||
@@ -80,6 +78,22 @@ public:
|
||||
|
||||
}
|
||||
|
||||
// display buffer/data properties
|
||||
void show_buffer(int numel = 128)
|
||||
{
|
||||
// show size of buffer
|
||||
std::cout<<"size of buffer "<<rawdata_.size()<<"\n\n";
|
||||
|
||||
// show excerpt from buffer
|
||||
int ista = 0, iend = numel;
|
||||
for ( int i= ista; i < iend; i++ )
|
||||
{
|
||||
std::cout<<std::hex<<(int)rawdata_[i]<<" ";
|
||||
if ( (i+1)%16 == 0 ) std::cout<<"\n";
|
||||
}
|
||||
std::cout<<"\n";
|
||||
}
|
||||
|
||||
// show predefined markers
|
||||
void show_markers()
|
||||
{
|
||||
@@ -135,6 +149,9 @@ public:
|
||||
{
|
||||
markseq.push_back(rawdata_[didx]);
|
||||
}
|
||||
|
||||
// obtain length of data segment
|
||||
datsize_ = markseq.size();
|
||||
}
|
||||
datasec_.insert(std::pair<std::string,std::vector<unsigned char>>(mrk.first,markseq));
|
||||
}
|
||||
@@ -198,12 +215,9 @@ public:
|
||||
// convert actual measurement data
|
||||
void convert_data()
|
||||
{
|
||||
// length of data array
|
||||
unsigned long int datsize = datasec_["datas marker"].size();
|
||||
assert ( (datsize_-28)%4 == 0 && "length of buffer is not a multiple of 4" );
|
||||
|
||||
assert ( (datsize-28)%4 == 0 && "length of buffer is not a multiple of 4" );
|
||||
|
||||
unsigned long int totnumfl = (datsize-28)/4;
|
||||
unsigned long int totnumfl = (datsize_-28)/(int)sizeof(float);
|
||||
for ( unsigned long int numfl = 0; numfl < totnumfl; numfl++ )
|
||||
{
|
||||
// assuming 4 byte float
|
||||
@@ -211,6 +225,8 @@ public:
|
||||
uint8_t* pnum = reinterpret_cast<uint8_t*>(&num);
|
||||
for ( int byi = 0; byi < (int)sizeof(float); byi++ )
|
||||
{
|
||||
// TODO what's the byte order in the file??
|
||||
// for now, we just don't care...
|
||||
pnum[byi] = (int)datasec_["datas marker"][(unsigned long int)(28+numfl*sizeof(float)+byi)];
|
||||
}
|
||||
|
||||
@@ -219,6 +235,61 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// convert half-precision (16bit) floating point numbers
|
||||
void convert_data_16_bit_float()
|
||||
{
|
||||
// single (32bit) floating point number
|
||||
float fl = 0.0;
|
||||
|
||||
unsigned long int totnumby = (datsize_-28)/2;
|
||||
for ( unsigned long int by = 0; by < totnumby; by++ )
|
||||
{
|
||||
// retrieve two bytes of floating point number
|
||||
std::vector<uint8_t> pnum;
|
||||
for ( int i = 0; i < 2; i++ ) pnum.push_back(datasec_["datas marker"][(unsigned long int)(28+by*2+i)]);
|
||||
|
||||
// obtain bitset
|
||||
std::bitset<8> byA(pnum[0]), byB(pnum[1]);
|
||||
|
||||
// TODO all following code only works for little endian!!
|
||||
|
||||
// sign
|
||||
float sign = byB[0];
|
||||
|
||||
// exponent of 16bit float
|
||||
long int expo = 0;
|
||||
for ( int i = 0; i < 5; i++ ) if ( byB[1+i] ) expo += pow(2.0,4-i);
|
||||
expo -= 15;
|
||||
|
||||
// convert to exponent of 32bit float
|
||||
|
||||
|
||||
// mantissa
|
||||
|
||||
|
||||
// declare bitset of float
|
||||
std::bitset<8> flA(0x00), flB(0x00), flC(0x00), flD(0x00);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// convert 16bit "decimal-encoding" floating point numbers
|
||||
void convert_data_16_bit_decimal()
|
||||
{
|
||||
//assert ( (datsize_-29)%2 == 0 && "length of buffer is not a multiple of 2" );
|
||||
|
||||
unsigned long int totnumby = (datsize_-30)/2;
|
||||
for ( unsigned long int by = 0; by < totnumby; by++ )
|
||||
{
|
||||
std::vector<uint8_t> pnum;
|
||||
for ( int i = 0; i < 2; i++ ) pnum.push_back(datasec_["datas marker"][(unsigned long int)(29+by*2+i)]);
|
||||
|
||||
datmes_.push_back((double)( (((int)pnum[0]-128)*256 + (int)pnum[1])/100.0 ));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// get data array encoded as floats/doubles
|
||||
std::vector<double>& get_data()
|
||||
{
|
||||
@@ -226,14 +297,14 @@ public:
|
||||
}
|
||||
|
||||
// write data to csv-like file
|
||||
void write_data(std::string filename)
|
||||
void write_data(std::string filename, int precision = 9)
|
||||
{
|
||||
// open file
|
||||
std::ofstream fout(filename.c_str());
|
||||
|
||||
for ( auto el : datmes_ )
|
||||
{
|
||||
fout<<std::dec<<el<<"\n";
|
||||
fout<<std::dec<<std::setprecision(precision)<<el<<"\n";
|
||||
}
|
||||
|
||||
// close file
|
||||
@@ -242,4 +313,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
Reference in New Issue
Block a user