如本网站所示:https://www.h-schmidt.net/FloatConverter/IEEE754.html
我已经查看过堆栈溢出的五个左右的帖子,但它们并不是我想要的。例如:
import struct
getBin = lambda x: x > 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]
def floatToBinary64(value):
val = struct.unpack('Q', struct.pack('d', value))[0]
return getBin(val)
def binaryToFloat(value):
hx = hex(int(value, 2))
return struct.unpack("d", struct.pack("q", int(hx, 16)))[0]
# floats are represented by IEEE 754 floating-point format which are
# 64 bits long (not 32 bits)
# float to binary
binstr = floatToBinary64(NUMBER)
print('Binary equivalent of .1:')
print(binstr + '\n')
# binary to float
fl = binaryToFloat(binstr)
print('Decimal equivalent of ' + binstr)
print(fl)
我意识到这与我正在寻找的非常接近。如果你将.1放入这个数字所在的代码中,它会将它列为.1,而在网站上它给我:0.10000000149011612。
如果有人能提供帮助那就太棒了!
答案 0 :(得分:2)
这只是因为Python向您展示了该数字的最佳表示。这个值实际上是这样的:
>>> '%.60f' % fl
'0.100000000000000005551115123125782702118158340454101562500000'
这正是文字0.1
变成的:
>>> '%.60f' % 0.1
'0.100000000000000005551115123125782702118158340454101562500000'
(哦,它不是0.10000000149011612因为用32而不是64位完成。实际上那个应该是0.100000001490116119384765625,转换器页面不准确。)
答案 1 :(得分:1)
您可以使用gmpy2库来处理任意精度二进制数,包括标准的32位和64位IEEE格式。
以下是一个例子:
>>> import gmpy2
>>> gmpy2.set_context(gmpy2.ieee(64))
>>> gmpy2.mpfr("0.1").__format__(".60f")
'0.100000000000000005551115123125782702118158340454101562500000'
>>> gmpy2.set_context(gmpy2.ieee(32))
>>> gmpy2.mpfr("0.1").__format__(".60f")
'0.100000001490116119384765625000000000000000000000000000000000'
编辑:添加了将mpfr转换为32位IEEE格式的示例函数。
import gmpy2
gmpy2.set_context(gmpy2.ieee(32))
def mpfr_to_float(x):
'''Convert an mpfr object created by the IEEE 32-bit compatible
context to a 32 character string containing 0 and 1.'''
# Check for special values first.
if gmpy2.is_infinite(x):
if gmpy2.is_signed(x):
return "1" * 9 + "0" * 23
else:
return "0" + "1" * 8 + "0" * 23
if gmpy2.is_nan(x):
return "0" + "1" * 31
if gmpy2.is_zero(x):
if gmpy2.is_signed(x):
return "1" + "0" * 31
else:
return "0" * 32
# Extract the mantissa, exponent, and precision. Note that the
# values are slightly different than the IEEE 32-bit standard.
mnt, exp, prc = x.digits(2)
# MPFR explicitely stores the leading bit of the mantissa so the
# precision is 24. To support subnormals, MPFR also uses a more
# negative minimum exponent and decreases the precision of the
# mantissa but maintains the leading '1' bit.
# Remove any leading sign bit from the mantissa string.
if mnt[0] == "-":
sign_char = "1"
mnt = mnt[1:]
else:
sign_char = "0"
# Check for subnormals
if exp + 126 <= 0:
# Drop the last bit since it will always be '0' and after the
# adjustments for subnormals, the leading bit will be '0'.
mnt = mnt[:-1]
else:
# Drop the leading '1' bit for normal numbers.
mnt = mnt[1:]
# Handle subnormals by shifting trailing bits from the mantissa
# string to the beginning. Adjust the exponent to match.
while exp + 126 < 0:
mnt = mnt[-1] + mnt[:-1]
exp = exp + 1
# Adjust the exponent to account for removing a bit from the
# mantissa string.
exp = exp - 1
# Add 127 to the exponent to account for the IEEE encoding.
exp = exp + 127
# Validate exponent range.
if (exp > 255) or (exp < 0):
raise ValueError("exp is out of bounds")
# Build and return the binary string.
result = sign_char + format(exp, "08b") + mnt
if len(result) != 32:
raise ValueError("something is wrong....")
return result
if __name__ == "__main__":
print(mpfr_to_float(gmpy2.mpfr("0.1")))
免责声明#1:这应该是对@Stefan Pochmann的答案的评论,但我认为代码示例会有所帮助。
免责声明#2:我维持gmpy2。