Velocity Reviews > Binary representation of floating point numbers

# Binary representation of floating point numbers

63q2o4i02@sneakemail.com
Guest
Posts: n/a

 12-06-2005
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

Grant Edwards
Guest
Posts: n/a

 12-06-2005
On 2005-12-06, http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:

> 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.

--
Grant Edwards grante Yow! ... I have read the
at INSTRUCTIONS...
visi.com

Mike Meyer
Guest
Posts: n/a

 12-06-2005
(E-Mail Removed) writes:
> 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
--
Mike Meyer <(E-Mail Removed)> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

63q2o4i02@sneakemail.com
Guest
Posts: n/a

 12-06-2005
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

63q2o4i02@sneakemail.com
Guest
Posts: n/a

 12-06-2005
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

So problem solved (just need to implement it).

Michael

Grant Edwards
Guest
Posts: n/a

 12-06-2005
On 2005-12-06, (E-Mail Removed) <(E-Mail Removed)> wrote:

> 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
>

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.

--
Grant Edwards grante Yow! I feel better about
at world problems now!
visi.com

Mike Meyer
Guest
Posts: n/a

 12-06-2005
(E-Mail Removed) writes:
> 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
--
Mike Meyer <(E-Mail Removed)> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

63q2o4i02@sneakemail.com
Guest
Posts: n/a

 12-06-2005
Actually that's probably the easiest way. I may want to use shorter
variable names

thanks
michael

Bengt Richter
Guest
Posts: n/a

 12-07-2005
On Tue, 06 Dec 2005 22:51:03 -0000, Grant Edwards <(E-Mail Removed)> wrote:

>On 2005-12-06, (E-Mail Removed) <(E-Mail Removed)> wrote:
>
>> 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
>>

>
>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

>>> class Bitview(long):

... 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)[i]
... 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,
>>> bv11

Bitview(int('00001011', 2))
>>> bv11[8]

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 9, in __getitem__
IndexError: 11L has only 8 bits
>>> 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

63q2o4i02@sneakemail.com
Guest
Posts: n/a

 12-07-2005
That looks pretty cool. I'll try it out.

thanks
Michael

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post suresh C++ 1 01-28-2011 07:18 AM Alex DeCaria Ruby 15 04-14-2010 03:46 PM Dilip C Programming 8 12-28-2006 06:36 AM sergei.s.mikhailov@gmail.com Java 3 06-22-2006 11:54 PM Motaz Saad Java 7 11-05-2005 05:33 PM