在Python中双倍转换为十进制值IEEE-754

时间:2016-09-20 11:39:18

标签: python double decimal ieee-754

我正在尝试将64位长的git branch -f master <good commit-ish>类型数据转换为十进制值。我关注https://en.wikipedia.org/wiki/Double-precision_floating-point_format 为了转换。

我在以下脚本中尝试过它:

private def fixChars(str: String): String = {
  val substitutions = Map(
    'Ø' -> 'O',
    'ø' -> 'o',
    ...
  )
  str.map(c => substitutions.getOrElse(c, c))
}

拜托,任何人都可以帮我解决这个问题。我无法理解我错在哪里?因为我可以使用double精确得到分数值,但每当尝试将其用于方程式时,它会在a = '\x3f\xd5\x55\x55\x55\x55\x55\x55' # Hexbyte representation of 1/3 value in double sign_bit = bin(ord(a[0])).replace('0b', '').rjust(8, '0')[0] sign = -1 ** int(sign_bit) print sign # Sign bit # Next 11 bits for exponent calculation exp_bias = 1023 a11 = bin(ord(a[0])).replace('0b', '').rjust(8, '0')[1:] + bin(ord(a[1])).replace('0b', '').rjust(8, '0')[:4] exp = int(a11, 2) print exp # Next 52 bits for fraction calculation fraction = bin(ord(a[1])).replace('0b', '').rjust(8, '0')[4:] + bin(ord(a[2])).replace('0b', '').rjust(8, '0') \ + bin(ord(a[3])).replace('0b', '').rjust(8, '0') + bin(ord(a[4])).replace('0b', '').rjust(8, '0') \ + bin(ord(a[5])).replace('0b', '').rjust(8, '0') + bin(ord(a[6])).replace('0b', '').rjust(8, '0') \ + bin(ord(a[7])).replace('0b', '').rjust(8, '0') print len(fraction), fraction fract = str(int(fraction, 2)) print len(fract), fract fin = repr(float(fract)/ 10 ** 16) print type(fin), fin # 16 digit precision # final value calculation according equation # eq = (-1)^sign * 2 ^(exp- exp_bias) * (1 + fin) val = 2 ** (exp - exp_bias) * float(fin) # Looses precision print val 中失去其精度。

无论如何还是替代方法来解决它?

2 个答案:

答案 0 :(得分:3)

执行此转换的简便方法是使用struct模块。

from struct import unpack

a = '\x3f\xd5\x55\x55\x55\x55\x55\x55'
n = unpack('>d', a)
print '%.18f' % n[0]

<强>输出

0.33333333333333331

在Python 3中,您需要将输入字符串和打包格式字符串指定为字节字符串,例如

a = b'\x3f\xd5\x55\x55\x55\x55\x55\x55'
n = unpack(b'>d', a)
print(format(n[0], '.18f'))

您还可以在Python 2中使用b字符串前缀(从2.6及更高版本,IIRC)。 Python 2只是忽略了该前缀,因为普通的Python 2字符串是字节字符串。

答案 1 :(得分:2)

工作太多了。

>>> import struct
>>> struct.unpack('>d', '\x3f\xd5\x55\x55\x55\x55\x55\x55')[0]
0.3333333333333333