What is the quickest way to convert 8 bytes to a Float object?
thanks for any help,
~harris
What is the quickest way to convert 8 bytes to a Float object?
thanks for any help,
~harris
On 8-Jun-06, at 8:20 PM, Harris R. wrote:
What is the quickest way to convert 8 bytes to a Float object?
thanks for any help,
~harris
Probably String#unpack where the string contains the 8 bytes. You
will have to pick the right one of the template directive depending
on the byte order of your data.
Mike
–
Mike S. [email protected]
http://www.stok.ca/~mike/
The “`Stok’ disclaimers” apply.
Harris R. wrote:
What is the quickest way to convert 8 bytes to a Float object?
thanks for any help,
~harris
ri Array#pack
flt = arr.pack(‘D’)
I am still not getting the results I am looking for hacking around with
the couple suggestions I received. Here is an example:
bytes = Array.new(8)
bytes[0] = 64
bytes[1] = 53
bytes[2] = 0
bytes[3] = 0
bytes[4] = 0
bytes[5] = 0
bytes[6] = 0
bytes[7] = 0
Calling:
binary_string = bytes.pack(‘D’)
returns a binary string, but not the float which should be 21.0; if I
turn around and call
binary_string.unpack(‘d’), I end up with the original bytes.
It is turning out that getting from bytes to a Float object is a bit
painful. Is there something easy I am missing?
thanks,
~harris
----- Original Message ----
From: Timothy H. [email protected]
To: ruby-talk ML [email protected]
Sent: Thursday, June 8, 2006 8:26:52 PM
Subject: Re: Converting 8 bytes to a Float
Harris R. wrote:
What is the quickest way to convert 8 bytes to a Float object?
thanks for any help,
~harris
ri Array#pack
flt = arr.pack(‘D’)
On 8-Jun-06, at 8:47 PM, Harris R. wrote:
bytes[6] = 0
It is turning out that getting from bytes to a Float object is a
bit painful. Is there something easy I am missing?
You should be using unpack . In irb:
ratdog:~ mike$ irb
irb(main):001:0> s = “”
=> “”
irb(main):002:0> s << 64 << 53 <<“\0” * 6
=> “@5\000\000\000\000\000\000”
irb(main):003:0> s.unpack(‘D’)
=> [21.0]
Mike
–
Mike S. [email protected]
http://www.stok.ca/~mike/
The “`Stok’ disclaimers” apply.
On Fri, 9 Jun 2006, Harris R. wrote:
bytes[7] = 0
thanks,
~harris
you just need to pack them into a binary string period, since you have
the
bytes you don’t need to pack them as a float, eg:
harp:~ > cat a.rb
f = 21
buf = [f].pack ‘D’
bytes = buf.unpack ‘c*’
p bytes
buf = bytes.pack ‘c*’
f = buf.unpack(‘D’).first
p f
harp:~ > ruby a.rb
[0, 0, 0, 0, 0, 0, 53, 64]
21.0
regards.
-a
Harris R. wrote:
bytes[7] = 0
I was wrong about pack. String#unpack is what you need, as others have
suggested.
Mike… thanks for the tip. My mileage is varying though… here is the
same irb session on my machine:
irb(main):004:0> s = “”
=> “”
irb(main):005:0> s << 64 << 53 << “\0” * 6
=> “@5\000\000\000\000\000\000”
irb(main):006:0> s.unpack(‘D’)
=> [6.73510288410787e-320]
I’m not getting the clean result for some reason.
~harris
----- Original Message ----
From: Mike S. [email protected]
To: ruby-talk ML [email protected]
Sent: Thursday, June 8, 2006 8:57:06 PM
Subject: Re: Converting 8 bytes to a Float
On 8-Jun-06, at 8:47 PM, Harris R. wrote:
bytes[6] = 0
It is turning out that getting from bytes to a Float object is a
bit painful. Is there something easy I am missing?
You should be using unpack . In irb:
ratdog:~ mike$ irb
irb(main):001:0> s = “”
=> “”
irb(main):002:0> s << 64 << 53 <<“\0” * 6
=> “@5\000\000\000\000\000\000”
irb(main):003:0> s.unpack(‘D’)
=> [21.0]
Mike
–
Mike S. [email protected]
http://www.stok.ca/~mike/
The “`Stok’ disclaimers” apply.
This is good stuff. I am now getting the correct Float object (21.0)
from a string of bytes (“@5\000\000\000\000\000\000”). Now… here is a
question… is there an easy way to go from the Float back to bytes.
This seems like it may be much more difficult.
something like this…
float_object = 21.0
bytes = SOME_API_HERE.convert(float_object)
I think a result of this work I am doing should be a general purpose
BitConverter class similar to what .Net offers. This would make working
with binary data in Ruby much less painful.
thanks for any help,
~harris
p.s. Mike… thanks a bunch for the help on going from Bytes to a
Float!!! I owe you… are you going to be at RailsConf?
----- Original Message ----
From: Mike S. [email protected]
To: ruby-talk ML [email protected]
Sent: Thursday, June 8, 2006 10:49:36 PM
Subject: Re: Converting 8 bytes to a Float
On 8-Jun-06, at 10:39 PM, Harris R. wrote:
I’m not getting the clean result for some reason.
I’m on a PowerPC, and you’re probably on an x86. Our endian-ness is
different.
D uses native format to unpack the bytes, if your bytes are laid out
the way you said they are then you probably want to use G which is
specifically “big endian”.
See Endian - Wikipedia for more background.
Hope this helps,
Mike
–
Mike S. [email protected]
http://www.stok.ca/~mike/
The “`Stok’ disclaimers” apply.
On 6/9/06, Harris R. [email protected] wrote:
This is good stuff. I am now getting the correct Float object (21.0) from a string of bytes
(“@5\000\000\000\000\000\000”). Now… here is a question… is there an easy way to go
from the Float back to bytes. This seems like it may be much more difficult.something like this…
float_object = 21.0
bytes = SOME_API_HERE.convert(float_object)
Hi Harris,
Keep in mind for things like this you always have the method pair
Array#pack and String#unpack:
C:\P4WS>irb
irb(main):001:0> f = 21.0
=> 21.0
irb(main):002:0> b = [f].pack(“D”)
=> “\000\000\000\000\000\0005@”
irb(main):003:0> b.unpack(“D”)
=> [21.0]
Ryan
On 8-Jun-06, at 10:39 PM, Harris R. wrote:
I’m not getting the clean result for some reason.
I’m on a PowerPC, and you’re probably on an x86. Our endian-ness is
different.
D uses native format to unpack the bytes, if your bytes are laid out
the way you said they are then you probably want to use G which is
specifically “big endian”.
See Endian - Wikipedia for more background.
Hope this helps,
Mike
–
Mike S. [email protected]
http://www.stok.ca/~mike/
The “`Stok’ disclaimers” apply.
Thanks Ryan… I had orignally thought this shouldn’t be any harder
than calling unpack coming from the oposite direction; nonetheless it
didn’t dawn on me to simply stuff the float into an array and call pack.
Gotta love learning a new language! Thanks,
~harris
----- Original Message ----
From: Ryan L. [email protected]
To: ruby-talk ML [email protected]
Sent: Friday, June 9, 2006 5:55:56 PM
Subject: Re: Converting a Float back to bytes
On 6/9/06, Harris R. [email protected] wrote:
This is good stuff. I am now getting the correct Float object (21.0) from a string of bytes
(“@5\000\000\000\000\000\000”). Now… here is a question… is there an easy way to go
from the Float back to bytes. This seems like it may be much more difficult.something like this…
float_object = 21.0
bytes = SOME_API_HERE.convert(float_object)
Hi Harris,
Keep in mind for things like this you always have the method pair
Array#pack and String#unpack:
C:\P4WS>irb
irb(main):001:0> f = 21.0
=> 21.0
irb(main):002:0> b = [f].pack(“D”)
=> “\000\000\000\000\000\0005@”
irb(main):003:0> b.unpack(“D”)
=> [21.0]
Ryan
Here are two functions in javascript that convert a double to and from a
hex encoded byte stream. They are part of a larger class but should
more or less make sense.
Some notes:
There is a good article on wikipedia about this:
Charlie
readDouble: function()
{
// Read IEEE 754 64-bit (8 bytes) double
var doubleHex = this.hex.slice(this.pos, this.pos + 16)
this.pos += 16
if (this.byteOrder == Geometry.WKB.WKB_NDR)
doubleHex = Geometry.WKB.swapEndian(doubleHex)
// get first 12 bits
var signExponentHex = doubleHex.slice(0, 3)
var signExponent = parseInt(signExponentHex, 16)
// get sign and exponent
var sign = signExponent & 0x800
var exponent = signExponent & 0x7FF
// get fraction which is 52 bits
var fractionHex = doubleHex.slice(3, 16)
var fraction = parseInt(fractionHex, 16)
if (exponent == 2047 && fraction != 0)
{
// NaN - Not a number
value = Number.NaN
}
else if (exponent == 2047 && fraction == 0 && sign == 1)
{
// Negative infinity
value = Number.NEGATIVE_INFINITY
}
else if (exponent == 2047 && fraction == 0 && sign == 0)
{
// Positive infinity
value = Number.POSITIVE_INFINITY
}
else if (exponent > 0 && exponent < 2047)
{
// Most significant byte should be 1 in normalized form
fraction += Math.pow(2,52)
value = fraction * Math.pow(2, exponent - 1023 - 52)
if (sign)
value = -value
}
else if (exponent == 0 && fraction != 0)
{
// Denormal number
value = fraction * Math.pow(2, -1022 - 52);
if (sign)
value = -value
}
else if (exponent == 0 && fraction == 0 && sign == 1)
{
// Negative zero
value = 0
}
else if (exponent == 0 && fraction == 0 && sign == 0)
{
// Positive zero
value = 0
}
else
{
throw new Error('Could not parse floating point number')
}
return value
}
writeDouble: function(value)
{
// get integer and fraction
var positiveValue = Math.abs(value)
var integer = Math.floor(positiveValue)
var fraction = positiveValue - integer
var intBin = integer.toString(2)
// convert to fraction, then remove leading "0."
var fractionBin = fraction.toString(2).slice(2)
var exponent = null
var significandBin = null
if (integer >= 1)
{
// Figure out exponent - 1023 is the bias bias
exponent = 1023 + intBin.length - 1
significandBin = intBin.slice(1) + fractionBin
}
else
{
var index = fractionBin.search(/1/)
if (index == -1)
{
exponent = 0
significandBin = "0"
}
else
{
// figure out exponent - 1023 is the bias bias
exponent = 1023 - index - 1
significandBin = fractionBin.slice(index + 1)
}
}
// write sign bit
if (value < 0)
bin = "1"
else
bin = "0"
// write exponent which is 11 bits
bin += this.padLeft(exponent.toString(2), 11)
// write the significand which is 52 bits
bin += this.padRight(significandBin, 52)
// Now convert to hex one byte at a time
var value = ""
for (var i=0; i<8; i++)
{
var temp = parseInt(bin.slice(i*8, i*8+8),2)
// Geos only accepts hex values in upper case
var upper = temp.toString(16).toUpperCase()
value += this.padLeft(upper.toString(16),2)
}
if (this.byteOrder == Geometry.WKB.WKB_NDR)
value = Geometry.WKB.swapEndian(value)
this.hex += value
}
Harris,
On Sat, Jun 10, 2006 at 07:22:07 +0900, Harris R. wrote:
Thanks Ryan… I had orignally thought this shouldn’t be any harder than
calling unpack coming from the oposite direction; nonetheless it didn’t
dawn on me to simply stuff the float into an array and call pack.Gotta love learning a new language! Thanks,
Usually I would keep my mouth shut about this sort of thing but I can’t
help
it on this occasion. The message I’m replying to is practically
unreadable
thanks to the top posting. Please read and consider this:
I shall now become an observer again
Cheers,
Phil
On Jun 9, 2006, at 5:44 PM, Harris R. wrote:
I think a result of this work I am doing should be a general
Mike… thanks for the tip. My mileage is varying though… here
Hope this helps,
Mike
–
Mike S. [email protected]
Mike StokThe “`Stok’ disclaimers” apply.
[21.0].pack(“D”) no?
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs