[英]How can I make this binary to float algorithm more efficient / shortened
因此,該算法將用戶二進制輸入作為xxxx.xxxx接收,然后輸出等效的十進制數。 保持相同的格式和樣式,如何縮短/提高效率?
import math
binary = {"Input":input("Enter your binary value here in the format of x.x : ").split("."), "Int":0, "Float":0}
for k, v in enumerate(binary["Input"][0][::-1]):
if int(v) == 1:
binary["Int"]= binary["Int"] + (2**(k))
for k, v in enumerate(binary["Input"][1]):
if int(v) == 1:
binary["Float"] = binary["Float"]+ (1/math.pow(2,k+1))
print(binary["Float"]+binary["Int"])
為了提高效率,最好只對字符串進行一次傳遞。
當前,您執行三遍:拆分,反向(部分)和計算。
另外,不要執行binary[...]
,只使用變量。
這是一個執行一遍的實現:
def bin2float(s):
result = exp = 0
for k in s:
if k == ".":
exp = 1
continue
result *= 2
exp *= 2
if k == '1':
result += 1
exp = max(exp, 1)
return result / exp
print(bin2float('Enter your binary value here in the format of x.x :')
如果只是在縮短之后,請使用單個變量,並使用+=
,也不要使用int(v) == '1'
,而不要使用v == '1'
,並使用math.pow(2, -k-1)
而不是(1/math.pow(2,k+1))
。
使用hex
而不是循環進行計算的版本(未經測試!):
def bin_str_to_hex_str(bin_str):
'''
extend the binary number after the '.' such that its length is a multiple
of 8; convert to hex.
'''
a, b = bin_str.split('.')
while len(b)%8 != 0:
b += '0'
hex_str = '{}.{}p+0'.format(hex(int(a,2)), hex(int(b,2))[2:])
return hex_str
def bin_str_to_float(bin_str):
hex_str = bin_str_to_hex_str(bin_str)
return float.fromhex(hex_str)
print(bin_str_to_float('010010010.010010101')) # -> 146.291015625
誠然,這會轉換兩次(一次是十六進制字符串,然后是十六進制字符串本身),這不是很好。。。可能有一種更聰明的方式來組裝零件。
def bin2Dec(bin_value):
bin_value = '0' + bin_value #to avoid the input format case, like '.11'
parts = bin_value.split(".")
integer_part = int(parts[0],2)
fraction_part = 0
if len(parts) == 2:
fraction_part = sum([int(val) * (10 ** (-id)) for id, val in enumerate(parts[1],start = 1)])
return integer_part + fraction_part
整數部分可以通過內置函數int
from math import pow as pow
import timeit
def bin2float(bin_str):
index = bin_str.index('.')
high = bin_str[:index]
low = bin_str[index+1:]
high_f = int(high,2)
low_f = int(low,2)/pow(2,len(low))
return high_f+low_f
def b2f(bin):
int_s,float_s =bin.split(".")
int_v = 0
float_v =0
for k, v in enumerate(int_s[::-1]):
if int(v) == 1:
int_v += (2**(k))
for k, v in enumerate(float_s):
if int(v) == 1:
float_v += (1/pow(2,k+1))
return int_v+float_v
if __name__ == "__main__":
bin ='010010010.010010101'
stmt1 = "bin2float('{0}')".format(bin)
stmt2= "b2f('{0}')".format(bin)
print(timeit.timeit(stmt1,"from bin2float import bin2float",number =10000 ))
print(timeit.timeit(stmt2,"from bin2float import b2f",number =10000 ))
測試結果:
0.015675368406093453
0.08317904950635754
實際上,您處理浮動部分的方式就等於
int(low,2)/pow(2,len(low))
從整體上處理零件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.