3

我一直在寻找是否有一种方法可以将浮点数(例如123.456:)转换为 binary32。我发现了很多从 binary32 到 float 的解决方案,但反之则不然。

4

3 回答 3

7

“时髦”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" %...像以前一样使用以显示它)。

于 2013-07-18T21:05:37.613 回答
6

以上很棒,但我有一些简化:

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

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

于 2013-07-25T22:27:03.940 回答
3

您应该使用String#unpackArray#pack

[123.456].pack('g').unpack('B*').first
#=> "01000010111101101110100101111001"
于 2017-01-08T22:03:36.537 回答