簡體   English   中英

如何使此二進制浮點算法更有效/更短

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM