2013-07-18 57 views
2

我一直在寻找是否有一种方法,将浮点数(例如:123.456)转换为二进制32。我发现很多从binary32到float的解决方案,但反过来也是如此。红宝石浮动到Binary32

+0

可能重复[如何转换binary32漂浮在红宝石(http://stackoverflow.com/questions/9698101/how-to-convert-binary32 - 浮动在红宝石) – tadman

+0

我看到那篇文章,但不知道它是如何工作的。我觉得它是因为Ruby中的一切都是一个对象,我需要以某种方式获得实际的浮动数。 – TakaGoto

+1

'pack'和'unpack'对于在二进制格式之间转换很有用。无论如何,一切都是一个对象,甚至是浮点数。为了逆转'unpack'的过程,你通常只需要用相同的规范调用'pack'。 – tadman

回答

4

以上是真棒,但我有几个简化:

[123.456].pack('g').bytes.map{|n| "%08b" % n}.join 

使用'g'标志,而不是'e'避免了必须reversepack输出。 bytes方法与在每个字符上调用.ord的功能相同。 然后,不是采用4个整数并进行总和/位移,而是将每个整数映射为8个字符的二进制字符串并将它们连接在一起。

+0

'g'选项是一个很好的捕获,并且摆脱了'reverse'。但是,您所展示的解决方案没有(作为中间值)我认为@TakaGoto所需的整个二进制值(而不仅仅是ASCII二进制字符串)。这就是'注入'在我提出的解决方案中所做的。因此,输出二进制的解决方案是'[123.456] .pack('g')。each_char.inject(0){| sum,c | sum =(sum << 8)+ c.ord}'。 – lurker

4

“时髦”y\xE9\xF6B值是以字符串表示的实际二进制值。

如果你想将其转换成二进制值的字符串表示:

"%032b" % [123.456].pack('e').reverse.each_char.inject(0) { |sum,c| sum = (sum << 8) + c.ord } 
=> "01000010111101101110100101111001" 

所以,要打破它,这给你包装成一个字符串“时髦”的二进制值:

[123.456].pack('e') 

其余转换“二进制串”成一个整数(“铸造”浮子的适当的二进制位数为整数):

reverse    # Handles the endian-ness 
each_char    # Grabs each character in the reversed string 
inject    # Concatenates the chars converted directly to binary 

然后"%032b" %将其显示为二进制字符串,以便您查看它。

编辑:由于@looby机敏地观察到的,“G”可以在pack而不是“E”被用来避免reverse步骤,缩短该溶液:[123.456].pack('g').each_char.inject(0) { |sum,c| sum = (sum << 8) + c.ord }(并且为了将其显示为在使用前"%032b" %...)。

+0

* + 1 * ...非常好的回答和* + 1 * ... –

2

您应该使用String#unpackArray#pack

[123.456].pack('g').unpack('B*').first 
#=> "01000010111101101110100101111001"