Binary representation of floating point numbers

6

63q2o4i02

Hi,

I'm using python to run some lab equipment using PyVisa. When I read a
list of values from the equipment, one of the fields is 32 bits of
flags, but the value is returned as a floating point number, either in
ASCII format, or pure binary. In either case, since I'm using PyVisa,
it converts the number to a single precision floating point, and that's
what I have to work with.

The question is how do I recover the bits out of this floating point
value so I can read the flags represented here?

Also, it's little (or big?) endian. Whatever... how do I manipulate
the endianness?

thanks
Michael
 
G

Grant Edwards

I'm using python to run some lab equipment using PyVisa. When I read a
list of values from the equipment, one of the fields is 32 bits of
flags, but the value is returned as a floating point number, either in
ASCII format, or pure binary.

Wha? That doesn't make any sense. If it's 32 bits of flags,
then it's not a floating point number "in pure binary".

I suppose you could pretend the 32 bit chunk is a float and
print the resulting value, but that's just insane. And it
won't work. For some bit patterns, there's no way to go from
ASCII back to that same bit pattern. IOW, there is not a 1:1
mapping between bit patterns and the string representation, so
if that's what you've got, you're screwed.
In either case, since I'm using PyVisa, it converts the number
to a single precision floating point, and that's what I have
to work with.

It sounds like PyVisa is broken if it's treating someting as a
float when it isn't.
The question is how do I recover the bits out of this floating
point value so I can read the flags represented here?

Use the struct module.
Also, it's little (or big?) endian. Whatever... how do I
manipulate the endianness?

Again, the struct module.
 
M

Mike Meyer

Hi,
I'm using python to run some lab equipment using PyVisa. When I read a
list of values from the equipment, one of the fields is 32 bits of
flags, but the value is returned as a floating point number, either in
ASCII format, or pure binary.

Value returned by *what*? Your equipment doesn't return floating
point numbers, it returns bytes. Those can be interpreted in any
number of ways. What you have to do is get those bytes into something
that lets you read the bits out of it. How you do that depends on how
you're getting the bytes.
In either case, since I'm using PyVisa,
it converts the number to a single precision floating point, and that's
what I have to work with.

If the conversion is anything but trivial, there's a fair chance the
information you're interested is destroyed by it.
The question is how do I recover the bits out of this floating point
value so I can read the flags represented here?

I'm not sure this is doable in Python. I'm not sure I *want* it to be
doable in Python. In C, you use a cast.
Also, it's little (or big?) endian. Whatever... how do I manipulate
the endianness?

On most processors, you don't. If you can, doing so will cause the OS
to come to a screeching halt on most of them. I don't know if anyone
still building boxes that treats the underlying platform as context to
the degree you're asking for here.

<mike
 
6

63q2o4i02

Hi,

okay, let me be more concise. The lab equipment has two formatting
modes, ascii, and float.

In ascii mode, it returns strings that represent the numeric value, so
e.g. 3.14 is returned as '3.14'. PyVisa, when set to read ascii mode,
will convert these strings to float with "visa.read_values()". (easy
enough to do myself too with visa.read(), split(), and eval()).

In float mode, the instrument returns a sequence of bits that are
exactly the ieee754 number in the case of floats, or just the flags in
the case of flags. PyVisa, when set to float mode, will convert
everything to float, because it is unaware apriori that one of the
fields returned is actually intended to be used as binary flags.

Secondarily, I had to set the instrument to return the bits in small
endian for it to read properly (I could aternately set PyVisa to swap
endianness for me). I may need to manipulate this.

Actually now that I read the very confusing manual, it looks like maybe
the flags is returned as a decimal number, but it's not clear how this
is returned in either ascii or float mode. In any case, I think I will
need to manipulate "native" numbers into binary representation. Looks
like I should figure out the struct module...

Michael
 
6

63q2o4i02

Ok, I figured it out...

The only way to get the flags is as a float, either through an ascii
string or a true float. The value of the float, however, is
representable as 24 bits of normal binary.

So for example, the value returned is +4.608400E+04
which is really an int, 46084, which is more easily convertible to
binary.

So the question becomes how to convert an int to binary, which I found
here
http://groups.google.com/group/comp...=python+int+to+binary&rnum=1#33bc9b0d8174b038

So problem solved (just need to implement it).

Michael
 
G

Grant Edwards

The only way to get the flags is as a float, either through an
ascii string or a true float.

That's perverse.

Really.

Somebody needs to be slapped.
The value of the float, however, is representable as 24 bits
of normal binary.

OK, that should preserve a 1:1 mapping between strings/floats
and flag bit patterns. It's still sick, though.
So for example, the value returned is +4.608400E+04 which is
really an int, 46084, which is more easily convertible to
binary.

You really don't need to convert it to "binary". Just convert
it to an integer object.
So the question becomes how to convert an int to binary, which
I found here

http://groups.google.com/group/comp...=python+int+to+binary&rnum=1#33bc9b0d8174b038

I doubt you actually want to do that. Just leave it as an
integer, and test for the bits you care about:

def bit(n):
return 1<<n

flags = int(half_assed_float_representing_the_flag_values)

if flags & bit(0):
print "underrange"
if flags & bit(1):
print "overrange"
if flags & bit(19):
print "bit 19 is set but nobody can hear me scream"
if flags & bit(23):
callThePolice()

or whatever.
 
M

Mike Meyer

In float mode, the instrument returns a sequence of bits that are
exactly the ieee754 number in the case of floats, or just the flags in
the case of flags. PyVisa, when set to float mode, will convert
everything to float, because it is unaware apriori that one of the
fields returned is actually intended to be used as binary flags.

You need to get PyVisa to return strings of bytes to you.
Actually now that I read the very confusing manual, it looks like maybe
the flags is returned as a decimal number, but it's not clear how this
is returned in either ascii or float mode. In any case, I think I will
need to manipulate "native" numbers into binary representation. Looks
like I should figure out the struct module...

Struct is the right tool for the job. But it manipulates strings of
bytes. If worst comes to worst, you could take the float returned by
PyVisa, use struct.pack to turn it into a string of bytes, then
struct.unpack to treat it as an integer on which you can do bit
manipulations. That works so long as everyone agrees about all the
details of the floating point representation. But you'd be better off
reading bytes and using struct.unpack to get an integer from them.

<mike
 
6

63q2o4i02

Actually that's probably the easiest way. I may want to use shorter
variable names :)

thanks
michael
 
B

Bengt Richter

That's perverse.

Really.

Somebody needs to be slapped.


OK, that should preserve a 1:1 mapping between strings/floats
and flag bit patterns. It's still sick, though.


You really don't need to convert it to "binary". Just convert
it to an integer object.


I doubt you actually want to do that. Just leave it as an
integer, and test for the bits you care about:

def bit(n):
return 1<<n

flags = int(half_assed_float_representing_the_flag_values)

if flags & bit(0):
print "underrange"
if flags & bit(1):
print "overrange"
if flags & bit(19):
print "bit 19 is set but nobody can hear me scream"
if flags & bit(23):
callThePolice()

or whatever.
You could also make a "whatever" like
... def __new__(cls, v, width=32):
... inst = long.__new__(cls, v)
... inst.width = width
... return inst
... def __getitem__(self, i):
... if isinstance(i, slice): return list(self)
... if i>=self.width or i+self.width<0:
... raise IndexError, '%r has only %r bits' %(long(self), self.width)
... if i<0: i = i + self.width
... bit = 1<<i
... return self&bit and 1 or 0
... def __repr__(self): return "Bitview(int('%s', 2))"% str(self)
... def __str__(self): return ''.join(map(str, self))[::-1]
...
>>> bv11 = Bitview(11, 8)
>>> bv11 Bitview(int('00001011', 2))
>>> bv11[8]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File said:
>>> list(bv11) [1, 1, 0, 1, 0, 0, 0, 0]
>>> bv11[::-1] [0, 0, 0, 0, 1, 0, 1, 1]
>>> bv11[-1] 0
>>> bv11[-5] 1
>>> bv11[-6] 0
>>> bv11[:4] [1, 1, 0, 1]
>>> str(bv11) '00001011'
>>> repr(bv11) "Bitview(int('00001011', 2))"
>>> eval(repr(bv11)) == bv11 True
>>> import sys
>>> Bitview(sys.maxint)
Bitview(int('01111111111111111111111111111111', 2))

Add niceties to taste ;-)
Regards,
Bengt Richter
 
T

Torsten Bronger

Hallöchen!

Sorry for the late response, but the subject didn't catch my
attention ...

Mike Meyer said:
You need to get PyVisa to return strings of bytes to you.

PyVISA does so when calling the read_raw() method.
[...]

Struct is the right tool for the job.

Exactly.

Tschö,
Torsten.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top