提问人:mitas1c 提问时间:5/1/2023 更新时间:5/1/2023 访问量:64
如何创建将 0 和 1 数组转换为浮点数的函数?[关闭]
How to create function that translates an array of 0 and 1s into a float? [closed]
问:
我正在尝试创建一个将数组作为参数的函数,该数组表示数字,但在二进制中,我希望此函数返回一个数字。
我可以将任何数字转换为二进制,但是我无法弄清楚如何从二进制中获取浮点数。
例如,4.8 是 [0, 1, 0, 0, 1, 1, 0, 0],但是当我像这样调用函数 binaryToFloat([0, 1, 0, 0, 1, 1, 0, 0]) 时,它返回 5.2 而不是 4.8。
但是,我只能使用下面提供的功能。 谁能帮我?
from typing import List, Callable
def bitNot(bit:int) -> int:
return 1 - bit
def bitAnd(bit1:int, bit2:int) -> int:
return bit1 * bit2
def bitOr(bit1:int, bit2:int) -> int:
return max(bit1, bit2)
def bitXor(bit1:int, bit2:int) -> int:
return bitOr(bit1, bit2) - bitAnd(bit1, bit2)
def map_array(function, array):
"""Použije funkci na každý prvek pole."""
result = []
for el in array:
result += [function(el)]
return result
def zipArray(arr1: List, arr2: List) -> List:
result: List = []
for i in range(len(arr1)):
result += [[arr1[i], arr2[i]]]
return result
"""
>>> zipArray([1, 2, 3], [4, 5, 6])
[[1, 4], [2, 5], [3, 6]]
"""
def mapTwoArrays(func: Callable, arr1: List, arr2: List) -> List:
def mapFunc(pair):
return func(pair[0], pair[1])
return map_array(mapFunc, zipArray(arr1, arr2))
def add(num: int, num2: int) -> int:
return num + num2
"""
>>> mapTwoArrays(add, [1, 2, 3], [4, 5, 6])
[5, 7, 9]
"""
def bitArrayAnd(arr1: List, arr2: List) -> List:
return mapTwoArrays(bitAnd, arr1, arr2)
def bitArrayOr(arr1: List, arr2: List) -> List:
return mapTwoArrays(bitOr, arr1, arr2)
def bitArrayXor(arr1: List, arr2: List) -> List:
return mapTwoArrays(bitXor, arr1, arr2)
def bitArrayLeftShift(arr: List, n: int) -> List:
return arr + (n * [0])
def bitArrayNot(arr: List) -> List:
return map_array(bitNot, arr)
"""
rekurze verze
def bitArrayRightShift(arr: List, n: int) -> List:
if n == 0:
return arr
else:
return bitArrayRightShift(arr[:-1], n -1)
"""
def bitArrayRightShift(arr: List, n: int) -> List:
return arr[:len(arr) - n]
def fillZeroes(arr: List, n: int) -> List:
return ([0] * n) + arr
def alignSize(arr: List, n: int) -> List:
return fillZeroes(arr, n - len(arr))
#pouze pomocí bitových operaci
def setBitOn(arr: List, i: int) -> List:
res: List = alignSize(bitArrayLeftShift([1], i), len(arr))
return bitArrayOr(arr, res)
def setBitOff(arr: List, i: int) -> List:
res: List = alignSize(bitArrayLeftShift([1], i), len(arr))
return map_array(bitNot,res)
def getBit(arr: List, i: int) -> List:
res: List = bitArrayRightShift(arr, i)
mask: List = alignSize([1], len(res))
return bitArrayAnd(res,mask)
#reprezentace nezáporných čísel v dvojkove soustave
def unsignedIntToBytes(num: int) -> List:
result: List = []
while num != 0:
bit: int = num % 2
result = [bit] + result
num = num // 2
return result
"""
>>> unsignedIntToBytes(5)
[1, 0, 1]
"""
def bitesToUnsignedInt(arr: List) -> int:
integer = 0
for i in range(len(arr)):
if arr[i] == 1:
integer += 2 ** (len(arr) - i - 1)
return integer
"""
>>> bitesToUnsignedInt([1, 0, 1])
5
"""
#cela cisla v binary
def numToBytes(num: int, size: int) -> List:
if num >= 0:
arr: List = unsignedIntToBytes(num)
fillSize = size - len(arr)
if fillSize <= 0:
raise ValueError(f'SIze of arr, to small, Missing {-fillSize+1} bit(s)')
return [0] * (size - len(arr)) + arr
else:
return bitArrayNot(numToBytes(-num - 1, size))
"""
>>> numToBytes(8, 8)
[0, 0, 0, 0, 1, 0, 0, 0]
>>> numToBytes(-8, 8)
[1, 1, 1, 1, 1, 0, 0, 0]
"""
def bytesToNum(arr: List) -> int:
signBit: int = arr[0]
if signBit == 0:
return bitesToUnsignedInt(arr)
else:
return -(bytesToNum(bitArrayNot(arr)) + 1)
"""
>>> bytesToNum([0, 0, 0, 0, 1, 0, 0, 0])
8
>>> bytesToNum([1, 1, 1, 1, 1, 0, 0, 0])
-8
"""
def nativeSetBitOn(num: int, i: int) -> int:
res: int = 1 << i
return num | res
def nativeSetBitOff(num: int, i: int) -> int:
res: int = ~(1 << i)
return num & res
"""
>>> native_set_bit_off(8, 3)
0
>>> native_set_bit_off(-1, 2)
-5
"""
def nativeGetBit(n: int, i:int) -> int:
res: int = n >> i
return res & n
"""
>>> nativeGetBit(8, 3)
1
"""
def nativeNumberToBitArray(num: int, size:int) -> List:
bit_array = []
for i in range(size-1, -1, -1):
bit = (num >> i) & 1
bit_array.append(bit)
return bit_array
"""
>>> nativeNumberToBitArray(5, 8)
[0, 0, 0, 0, 0, 1, 0, 1]
>>> nativeNumberToBitArray(-1, 8)
[1, 1, 1, 1, 1, 1, 1, 1]
"""
def getFirst(n:int) -> int:
return n & 1
"""
>>> getFirst(9)
1
"""
def getRest(n:int) -> int:
return n >> 1
"""
>>> getRest(9)
4
"""
def nativeNumberToBitArray2(num: int, size:int) -> List:
"""Převede číslo na seznam bitů. Používá native_get_bit."""
bit_array = []
for i in range(size-1, -1, -1):
bit_array.append(nativeGetBit(num, i) & 1)
return bit_array
"""
>>> nativeNumberToBitArray2(5, 8)
[0, 0, 0, 0, 0, 1, 0, 1]
>>> nativeNumberToBitArray2(-1, 8)
[1, 1, 1, 1, 1, 1, 1, 1]
"""
DAY_BIT_COUNT = 5
MONTH_BIT_COUNT = 4
YEAR_BIT_COUNT = 7
def encodeDate(date: List) -> int:
day = date[0] << (MONTH_BIT_COUNT + YEAR_BIT_COUNT)
month = date[1] << YEAR_BIT_COUNT
year = (date[2] - 2000) & ((1 << YEAR_BIT_COUNT) - 1)
return day | month | year
def decodeDate(date: int) -> List:
year = (date & ((1 << YEAR_BIT_COUNT) - 1)) + 2000
month = (date >> YEAR_BIT_COUNT) & ((1 << MONTH_BIT_COUNT) - 1)
day = date >> (YEAR_BIT_COUNT + MONTH_BIT_COUNT)
return [day, month, year]
#zápočet funkce co zakoduje a dekoduje zpět
#je to zápočet
#Rozšířit o rok
#[27,4,2033]
def floatToBinary(num: float, size: int):
int_part = int(num)
float_part = num - int_part
int_binary = numToBytes(int_part, size) # assuming 32-bit integers
float_binary = []
for i in range(size):
float_part *= 2
bit = int(float_part)
float_binary.append(bit)
float_part -= bit
return int_binary + float_binary
def floatToBytes(num: float) -> List[int]:
# Extract sign, exponent, and significand
sign = 0 if num >= 0 else 1
num = abs(num)
exponent = 0
while num >= 2.0:
num /= 2.0
exponent += 1
while num < 1.0:
num *= 2.0
exponent -= 1
significand = num - 1.0
# Convert sign, exponent, and significand to binary
sign_bits = [sign]
exponent_bits = numToBytes(exponent + 127, 8)
significand_bits = unsignedIntToBytes(int(significand * (1 << 23)))
# Combine sign, exponent, and significand bits
return sign_bits + exponent_bits + significand_bits
def binaryToFloat(bits: List[int]) -> float:
whole_part = 0
fractional_part = 0
for i in range(len(bits)):
if i < 4:
whole_part += bits[i] * (2 ** (3 - i))
else:
fractional_part += bits[i] * (2 ** (3 - (i - 4)))
return whole_part + (fractional_part / 10)
print(floatToBinary(4.8,4))
print(binaryToFloat([0, 1, 0, 0, 1, 1, 0, 0])) #Should be 4.8
答:
1赞
B Remmelzwaal
5/1/2023
#1
问题是您的小数部分计算不正确。小数部分的每个位代表 2 的幂倒数,即 1/2、1/4、1/8 等。
凭借这些固定点的精度,您可以获得的最佳值为 4.75,因为二进制中的 0.8 是 0.1100110011...
def binaryToFloat(bits: List[int]) -> float:
whole_part = 0
fractional_part = 0
for i in range(len(bits)):
if i < 4:
whole_part += bits[i] * (2 ** (3 - i))
else:
fractional_part += bits[i] / (2 ** (i - 3))
return whole_part + fractional_part
print(binaryToFloat([0, 1, 0, 0, 1, 1, 0, 0]))
评论
0赞
Eric Postpischil
5/1/2023
4.8125 在基数点后有四位(作为二进制 100.1101)的定点表示,比 4.75 更接近 4.8。
评论