473,327 Members | 2,103 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

bits of this, bits of that

Ben
Hi,

I need to write some data types into an array of unsigned chars.

These are basically "signals" within a message, so each signal will have
a start bit and a length. The signals will also have a type, one of:
unsigned long
signed long
float
double

The signals with float and double will be 32 or 64 bits long, as
appropriate.

I need to just shift the bits and throw them into the array, untouched.
Whats the best way of doing this?

Since I can't bit shift a float around, I was thinking of a union of the
4 types, and doing all the bit twiddling using the unsigned type. Is
this going to work, or am I asking for trouble? Presumably there's a
better way.

Cheers for any insights,

Ben
--
I'm not just a number. To many, I'm known as a String...
Aug 25 '05 #1
14 2420
> Hi,

I need to write some data types into an array of unsigned chars.

These are basically "signals" within a message, so each signal will have
a start bit and a length. The signals will also have a type, one of:
unsigned long
signed long
float
double

The signals with float and double will be 32 or 64 bits long, as
appropriate.

I need to just shift the bits and throw them into the array, untouched.
Whats the best way of doing this?

Since I can't bit shift a float around, I was thinking of a union of the
4 types, and doing all the bit twiddling using the unsigned type. Is
this going to work, or am I asking for trouble? Presumably there's a
better way.

Cheers for any insights,

Ben
--
I'm not just a number. To many, I'm known as a String...


I'm not sure I completely understand what you're trying to accomplish.
But looks like std::bitset can help you out here. Its a bit-vector and
provides constant time access to the bits. You can also shift around
bits and use bitwise operators on it.

Srini

Aug 25 '05 #2
Ben
Srini wrote:
Hi,

I need to write some data types into an array of unsigned chars.

These are basically "signals" within a message, so each signal will have
a start bit and a length. The signals will also have a type, one of:
unsigned long
signed long
float
double

The signals with float and double will be 32 or 64 bits long, as
appropriate.

I need to just shift the bits and throw them into the array, untouched.
Whats the best way of doing this?

Since I can't bit shift a float around, I was thinking of a union of the
4 types, and doing all the bit twiddling using the unsigned type. Is
this going to work, or am I asking for trouble? Presumably there's a
better way.

Cheers for any insights,

I'm not sure I completely understand what you're trying to accomplish.


OK, I'm trying to pack signals into a data frame to be sent over a
communications channel. Those signals can have 4 distinct types, which
are known a priori for each frame. The signals have a length (which may
be restricted by it's type), and a start bit within the frame.

So, a Signal of type float, would have 32 bits, and could start at say,
the 5 bit within a 64bit data frame.
But looks like std::bitset can help you out here. Its a bit-vector and
provides constant time access to the bits. You can also shift around
bits and use bitwise operators on it.


Thats interesting, but what is the recommended way of getting the bits
in my float into and out of the bitset?

Ben
--
I'm not just a number. To many, I'm known as a String...
Aug 25 '05 #3
> OK, I'm trying to pack signals into a data frame to be sent over a
communications channel. Those signals can have 4 distinct types, which
are known a priori for each frame. The signals have a length (which may
be restricted by it's type), and a start bit within the frame.

So, a Signal of type float, would have 32 bits, and could start at say,
the 5 bit within a 64bit data frame.

I don't think using floating point types and using them to pack data
into a frame is a good idea. 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.

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?
But looks like std::bitset can help you out here. Its a bit-vector and
provides constant time access to the bits. You can also shift around
bits and use bitwise operators on it.


Thats interesting, but what is the recommended way of getting the bits
in my float into and out of the bitset?


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.
Ben
--
I'm not just a number. To many, I'm known as a String...


Srini

Aug 25 '05 #4

Ben schreef:
Srini wrote:
Hi,

I need to write some data types into an array of unsigned chars.

These are basically "signals" within a message, so each signal will have
a start bit and a length. The signals will also have a type, one of:
unsigned long
signed long
float
double

The signals with float and double will be 32 or 64 bits long, as
appropriate.

I need to just shift the bits and throw them into the array, untouched.
Whats the best way of doing this?

Since I can't bit shift a float around, I was thinking of a union of the
4 types, and doing all the bit twiddling using the unsigned type. Is
this going to work, or am I asking for trouble? Presumably there's a
better way.

Cheers for any insights,

I'm not sure I completely understand what you're trying to accomplish.


OK, I'm trying to pack signals into a data frame to be sent over a
communications channel. Those signals can have 4 distinct types, which
are known a priori for each frame. The signals have a length (which may
be restricted by it's type), and a start bit within the frame.


Do you know the formats of the wire types? Are they identical to the
C++ types? After all, ISO C++ does not prescribe how the bits in a type
are used. In fact, for any type but char, there are at least 2 common
implementations (for char, the common implementation is 8 bits, but
even
this is not universal)
So, a Signal of type float, would have 32 bits, and could start at say,
the 5 bit within a 64bit data frame.


However, your C++ float may be 64 bits. Trouble...
But looks like std::bitset can help you out here. Its a bit-vector and
provides constant time access to the bits. You can also shift around
bits and use bitwise operators on it.


Thats interesting, but what is the recommended way of getting the bits
in my float into and out of the bitset?


The best way would be to find out what your wire protocol is (probably
1 sign bit, M mantissa bits and E exponent bits), calclulate the two
unsigned longs MBits and Ebits, with MBits < (1<<M) and EBits < (1<<E)
then add the sign bit, the lower M bits from MBits and the lower E bits
from EBits. If the base is 2, EBits is simple, calculate the 2-log. You
can then divide by 1<<EBits (or multiply by 1<<-EBits) to get MBits.
(base-16 is only a bit more tricky)

The advantage is that the algortihm works on the value of your float,
not the representation of this value in memory.

HTH,
Michiel Salters

Aug 25 '05 #5
"Ben" <benpope81@_pants_gmail.com> wrote in message
news:1124966345.3ee8ba9c41fbfb7817a747c0f7c4b794@t eranews...
Hi,

I need to write some data types into an array of unsigned chars.

These are basically "signals" within a message, so each signal will have a
start bit and a length. The signals will also have a type, one of:
unsigned long
signed long
float
double

The signals with float and double will be 32 or 64 bits long, as
appropriate.

I need to just shift the bits and throw them into the array, untouched.
Whats the best way of doing this?

Since I can't bit shift a float around, I was thinking of a union of the 4
types, and doing all the bit twiddling using the unsigned type. Is this
going to work, or am I asking for trouble? Presumably there's a better
way.

Cheers for any insights,


Why do you need different data types for the signals? I'd recommend to take
a look at vector<bool> or at the bitset classes for your application.

Cheers
Chris
Aug 25 '05 #6
Ben
msalters wrote:
Ben schreef:


That confused me for a moment, I wondered Ben schreef was!
OK, I'm trying to pack signals into a data frame to be sent over a
communications channel. Those signals can have 4 distinct types, which
are known a priori for each frame. The signals have a length (which may
be restricted by it's type), and a start bit within the frame.

Do you know the formats of the wire types? Are they identical to the
C++ types? After all, ISO C++ does not prescribe how the bits in a type
are used. In fact, for any type but char, there are at least 2 common
implementations (for char, the common implementation is 8 bits, but
even
this is not universal)


Yep, that problem I know about. There is only one platform / compiler
and it's correct.
So, a Signal of type float, would have 32 bits, and could start at say,
the 5 bit within a 64bit data frame.

However, your C++ float may be 64 bits. Trouble...


As above.
Thats interesting, but what is the recommended way of getting the bits
in my float into and out of the bitset?

The best way would be to find out what your wire protocol is (probably
1 sign bit, M mantissa bits and E exponent bits), calclulate the two
unsigned longs MBits and Ebits, with MBits < (1<<M) and EBits < (1<<E)
then add the sign bit, the lower M bits from MBits and the lower E bits
from EBits. If the base is 2, EBits is simple, calculate the 2-log. You
can then divide by 1<<EBits (or multiply by 1<<-EBits) to get MBits.
(base-16 is only a bit more tricky)

The advantage is that the algortihm works on the value of your float,
not the representation of this value in memory.


Yeah, understood. I might just have to go this route.

Ben
Aug 25 '05 #7
Ben
Srini wrote:
OK, I'm trying to pack signals into a data frame to be sent over a
communications channel. Those signals can have 4 distinct types, which
are known a priori for each frame. The signals have a length (which may
be restricted by it's type), and a start bit within the frame.

So, a Signal of type float, would have 32 bits, and could start at say,
the 5 bit within a 64bit data frame.
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.
Thats interesting, but what is the recommended way of getting the bits
in my float into and out of the bitset?


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_[i];
}
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
--
I'm not just a number. To many, I'm known as a String...
Aug 25 '05 #8
Ben wrote:
[snip]
Thats interesting, but what is the recommended way of getting the bits
in my float into and out of the bitset?
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:

[snip] float floatVal = 47/5;
frame.SetSignal(0, 32, reinterpret_cast<unsigned long>(floatVal));


If you want to use reinterpret_cast to do a bit-wise copy of a float
into a 32-bit int, you probably want something like this:

assert( sizeof(float) == sizeof(unsigned long) );
unsigned long uintVal = *reinterpret_cast<unsigned long*>( &floatVal
);

A compile-time assertion would be better than a run-time one, however.
See the Boost or Loki libraries for examples.

Cheers! --M

Aug 25 '05 #9
mlimber wrote:
Ben wrote:
[snip]
Thats interesting, but what is the recommended way of getting the bits
in my float into and out of the bitset?

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:


[snip]
float floatVal = 47/5;
frame.SetSignal(0, 32, reinterpret_cast<unsigned long>(floatVal));

If you want to use reinterpret_cast to do a bit-wise copy of a float
into a 32-bit int, you probably want something like this:

assert( sizeof(float) == sizeof(unsigned long) );
unsigned long uintVal = *reinterpret_cast<unsigned long*>( &floatVal
);

A compile-time assertion would be better than a run-time one, however.
See the Boost or Loki libraries for examples.


OK, I get it, cheers.

I seem to have it working with a nasty union at the moment, but the cast makes sense now I see it.

Ben
--
I'm not just a number. To many, I'm known as a String...
Aug 25 '05 #10
Chris Theis wrote:
Why do you need different data types for the signals? I'd recommend to take
a look at vector<bool> or at the bitset classes for your application.


It's up to the user to decide what the signals will be, usually they are integers, but it's possible that they will require floating point arithmetic, too.

I'm implementing some functionality for compatibility with an existing API.

Ben
--
I'm not just a number. To many, I'm known as a String...
Aug 25 '05 #11
Srini wrote:

Ex: If you want 50 bits,

std::bitset<50> bits_50;

You can get the unsigned long value of any bitset.


You can only get the unsigned long value of a bitset that
has 32 bits or fewer (or however many bits are in an
unsigned long on your system).

Aug 25 '05 #12
Old Wolf wrote:
Srini wrote:
Ex: If you want 50 bits,

std::bitset<50> bits_50;

You can get the unsigned long value of any bitset.

You can only get the unsigned long value of a bitset that
has 32 bits or fewer (or however many bits are in an
unsigned long on your system).


You can get the lower 32 bits into an unsigned long if the higher bits are not set, if they are it throws an error.

Ben
--
I'm not just a number. To many, I'm known as a String...
Aug 25 '05 #13
Ben wrote:
Hi,

I need to write some data types into an array of unsigned chars.

These are basically "signals" within a message, so each signal will have
a start bit and a length. The signals will also have a type, one of:
unsigned long
signed long
float
double

The signals with float and double will be 32 or 64 bits long, as
appropriate.

I need to just shift the bits and throw them into the array, untouched.
Whats the best way of doing this?

Since I can't bit shift a float around, I was thinking of a union of the
4 types, and doing all the bit twiddling using the unsigned type. Is
this going to work, or am I asking for trouble? Presumably there's a
better way.

Cheers for any insights,

Ben
--
I'm not just a number. To many, I'm known as a String...


Have you looked into BER (Basic Encoding Rules) and ASN.1 (Abstract
Syntax Notation)?

Free C source code and libraries for these two standards are available
on almost any platform (LDAP is implemented in BER). At the very least,
they would at least be instructive in showing how this kind of problem
has been solved before.

Greg

Aug 25 '05 #14
Ben
Greg wrote:

Have you looked into BER (Basic Encoding Rules) and ASN.1 (Abstract
Syntax Notation)?

Free C source code and libraries for these two standards are available
on almost any platform (LDAP is implemented in BER). At the very least,
they would at least be instructive in showing how this kind of problem
has been solved before.


Thats very interesting... I think those formalise what I'm talking about.

So if I were to write some ASN.1 for my signals, it would be possible to
have a set of libraries encode my data.

It would seem that I actually require a PER compiler, and that my data
has no preamble or length encoded within it, merely a value that is not
byte aligned.

Can anybody recommend any libraries that can do this?

Ben
--
I'm not just a number. To many, I'm known as a String...
Aug 26 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: cppaddict | last post by:
Hi, I am going to have a series of bit flags which I could store in an array, or as a string ("10011001"), or any other way. I want to be able to turn this series of bits into an int. I know...
11
by: Steve | last post by:
Hi, i know this is an old question (sorry) but its a different problem, i need to write a binary file as follows 00000011 00000000 00000000 00000101 00000000 11111111
13
by: Tomás | last post by:
The quantity of bits used by an unsigned integer type in memory can be determined by: typedef unsigned long long UIntType; CHAR_BIT * sizeof(UIntType) However, what would be a good...
12
by: Frederick Gotham | last post by:
Over on comp.lang.c, Hallvard B Furuseth devised a compile-time constant representing the amount of value representation bits in an unsigned integer type. In true C fashion, here it is as a macro:...
14
by: evangeli | last post by:
Hello, How can I know the number of bits used for an int value? Is "sizeof(int) * CHAR_BIT" correct ? thanks
23
by: Umesh | last post by:
This is a basic thing. Say A=0100 0001 in ASCII which deals with 256 characters(you know better than me!) But we deal with only four characters and 2 bits are enough to encode them. I want to...
11
by: Mack | last post by:
Hi all, I want to write a program to count number of bits set in a number. The condition is we should not loop through each bit to find whether its set or not. Thanks in advance, -Mukesh
77
by: borophyll | last post by:
As I read it, C99 states that a byte is an: "addressable unit of data storage large enough to hold any member of the basic character set of the execution environment" (3.6) and that a byte...
29
by: Virtual_X | last post by:
As in IEEE754 double consist of sign bit 11 bits for exponent 52 bits for fraction i write this code to print double parts as it explained in ieee754 i want to know if the code contain any...
11
by: JoeC | last post by:
I am working on a graphics program but my question has nothing to do with graphics but trying to get an algorithm to work. I set graphics from a 16x16 grid to bits of a graphic with: bitData =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.