Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a floating point hexadecimal to float in Ruby

I converted a floating point number say 1.012 to hexadecimal using Javascript by using the command 1.012.toString(16) and now what can be done to reverse the output of javascript 1.03126e978d4fe to 1.012 using Ruby ?

In short, what's the easiest way of reversing a floating point which was encoded as hexadecimal in Ruby?

Thanks.

like image 293
Ninja Boy Avatar asked Oct 20 '25 12:10

Ninja Boy


2 Answers

This is the weirdest conversion I ever saw.

i, m = "1.03126e978d4fe".split('.')
Integer("0x#{i}") + 1.0 * Integer("0x#{m}") / Integer("0x1#{'0' * m.length}")
#⇒ 1.012
like image 124
Aleksei Matiushkin Avatar answered Oct 22 '25 02:10

Aleksei Matiushkin


This output looked really weird at first, but it's actually consistent with our base-ten floats. 1.012 looks normal to us just because we use the decimal numeral system every day.

If I understand it correctly, the output can be seen as a rational with the numerator being the whole hex number (without '.') and the denominator being 16**(length of "decimal" part) :

def string_to_float(string, base = 10)
  string.delete('.').to_i(base).to_f / base**(string.reverse.index('.') || 0)
end

string_to_float('1.03126e978d4fe', 16)
#=> 1.012

string_to_float('1c.8', 16)
#=> 28.5

string_to_float('3.243f6a8885a3', 16)
#=> 3.141592653589793

string_to_float('20.0', 16)
#=> 32.0

string_to_float('20.', 16)
#=> 32.0

string_to_float('20', 16)
#=> 32.0

string_to_float('3.14159', 10)
#=> 3.14159

string_to_float('11.001001000011111101101010100010001000010110100011', 2)
#=> 3.141592653589793

If you only need to convert hex floats, you can remove the base argument :

def hex_string_to_float(hex)
  hex.delete('.').to_i(16).to_f / 16**(hex.reverse.index('.') || 0)
end
like image 22
Eric Duminil Avatar answered Oct 22 '25 02:10

Eric Duminil