Srini said:
I don't think using floating point types and using them to pack data
into a frame is a good idea.
I need to pack the floating point number into the frame, whether it's a
good thing to do or not is not up to me, I'm just providing the
functionality for my users. The data is specified as the format my
compiler uses, so I literally just need to transfer the bits in and out.
> If its just a particular number of bits
you want to use to pack into a frame, you can use std::bitset.
Ex: If you want 50 bits,
std::bitset<50> bits_50;
You can get the unsigned long value of any bitset.
OK.
And I still don't understand what you mean by "type of a signal". If
you want to capture the type of a signal in the frame you're sending so
that the other side can know what type of signal is in the frame, then
why not designate 2 bits in the frame to indicate the type of signal.
00 - unsigned long
01 - signed long
10 - float
11 - double
Would this meet your requirement or am I still wrong in understnading
your problem?
The signal types are known a priori, so there is no requirement to
specify the type, length etc within the frame. I just need the 32 bits
of a float or 64 bits of a double to be in the frame, offset by the
required startbit.
I do not know of any portable way of doing this. If you want to pack
the bits from a float variable into the frame, you could do a (an ugly)
reinterpret_cast.
Hmm, can't seem to make reinterpret_cast work:
#include <iostream>
#include <bitset>
#include <string>
#include <sstream>
#include <stdexcept>
class Frame {
public:
static const LENGTH = 64;
typedef std::bitset<LENGTH> Data;
Frame() : data_(0) {}
void SetSignal(size_t startBit, size_t length, unsigned long value) {
if (64 < startBit + length) {
throw std::range_error("Signal too long");
} else {
Data mask = ~(0xffffffff<<(length));
Data temp(value & mask.to_ulong());
data_ &= ~(mask<<(LENGTH-startBit-length));
data_ |= temp<<(LENGTH-startBit-length);
}
}
unsigned long GetSignal(size_t startBit, size_t length) {
if (64 < startBit + length) {
throw std::range_error("Signal too long");
} else {
Data mask = ~(0xffffffff<<(length));
Data temp = data_>>(LENGTH-startBit-length);
temp &= mask;
return temp.to_ulong();
}
}
std::string ToString() {
std::stringstream ss;
for (int i = LENGTH-1; i>=0; --i) {
if (7 == i%8) {
ss << std::endl << 7-i/8 << ": ";
} else if (3 == i%4) {
ss << " ";
}
ss << data_
;
}
return ss.str();
}
private:
Data data_;
};
int main(int argc, char* argv[])
{
Frame frame;
std::cout << frame.ToString() << std::endl << std::hex;
int intVal = 0x55;
frame.SetSignal(32, 8, intVal);
std::cout << frame.ToString() << std::endl;
std::cout << "0x" << frame.GetSignal(32, 8) << std::endl;
float floatVal = 47/5;
frame.SetSignal(0, 32, reinterpret_cast<unsigned long>(floatVal));
std::cout << frame.ToString() << std::endl;
std::cout << "0x" << reinterpret_cast<float>(frame.GetSignal(0, 32))
<< std::endl;
return 0;
}
What do you think? In VC7.1 I get:
test.cpp(61): error C2440: 'reinterpret_cast' : cannot convert from
'float' to 'unsigned long'
Conversion is a valid standard conversion, which can be
performed implicitly or by use of static_cast, C-style cast or
function-style cast
Ben