正负分数转二进制
positive and negative fraction to binary conversion
我正在尝试将正分数和负分数转换为二进制,我在网上找到了以下方法 (https://www.geeksforgeeks.org/convert-decimal-fraction-binary-number/) 将正分数转换为二进制并尝试扩展它以支持负分数。
我正在尝试对小数部分进行 2 的补码。非常感谢任何帮助。
# decimal to binary number
# Function to convert decimal to binary
# upto k-precision after decimal point
def decimalToBinary(num, k_prec) :
binary = ""
# Fetch the integral part of
# decimal number
Integral = int(num)
# Fetch the fractional part
# decimal number
fractional = num - Integral
# Conversion of integral part to
# binary equivalent
while (Integral) :
rem = Integral % 2
# Append 0 in binary
binary += str(rem);
Integral //= 2
# Reverse string to get original
# binary equivalent
binary = binary[ : : -1]
# Append point before conversion
# of fractional part
binary += '.'
# Conversion of fractional part
# to binary equivalent
while (k_prec) :
# Find next bit in fraction
fractional *= 2
fract_bit = int(fractional)
if (fract_bit == 1) :
fractional -= fract_bit
binary += '1'
else :
binary += '0'
k_prec -= 1
if (num < 0): # if negative numbers do the two's complement
binary = ~binary # struck here.
else:
binary = binary
return binary
# Driver code
if __name__ == "__main__" :
num_list=[1, 0, 0.924, -0.383]
for i in num_list:
print(i, decimalToBinary(i,8))
macky@test:~/test$ python frac_to_binary.py
(1, '1.00000000')
(0, '.00000000')
(0.924, '.11101100')
Traceback (most recent call last):
File "frac_to_binary.py", line 63, in <module>
print(i, decimalToBinary(i,8))
File "frac_to_binary.py", line 54, in decimalToBinary
binary = ~binary
TypeError: bad operand type for unary ~: 'str'
实际上有几种方法可以将二进制数显示为负数。要记住的重要一点是注意您的位大小;将您的位大小设置为大于您要转换的最大值,否则可能会发生奇怪的事情:
- bits = 4 for numbers <= 7 (
0111
)
- bits = 5 for numbers <= 15 (
01111
)
- bits = 8 for numbers <= 127 (
01111111
)
另一件要记住的事情是你必须转换整个二进制表示,而不是每个部分。
我修改了你的函数以显示四种类型的表示:Signed、Sign Magnitude、One's Complement,和补码:
NOTE - Tested on CentOS 7.9, using Python 2.7, and on Ubuntu 20.04, using Python 3.8
"""Program to convert rational numbers to signed and unsigned binary representations
Signed: Add a sign (0001 = 1, -0001 = -1)
Sign Magnitude: The sign is the most significant bit (0001 = 1, 1001 = -1)
One's Complement: Flip all the bits to their opposite value (0001 = 1, 1110 = -1)
Two's Complement: Flip all the bits, then add 1 to the least significant bit (0001 = 1, 1111 = -1)
Signed and decimal values checked at
https://www.rapidtables.com/convert/number/binary-to-decimal.html
Complements checked at https://planetcalc.com/747/
Warning: Set your bit size larger than the max value that you want to convert:
bits = 4 for numbers <= 7 (0111)
bits = 5 for numbers <= 15 (01111)
...
bits = 8 for numbers <= 127 (01111111)
"""
def decimal_to_binary(num, bits):
"""Function to convert rational numbers to binary representations
:param float num: The decimal to convert to binary
:param int bits: The bit size; see warning in the module docstring
:return: A formatted string with Signed, Sign Mag, One's Comp, and Two's Comp representations
:rtype: str
"""
# Ensure the number is a float
num *= 1.0
# Separate the number's components
whole_part = int(str(num).split(".")[0])
decimal_part = float("." + str(num).split(".")[1])
# Convert the whole part to binary
if whole_part >= 0:
whole_binary = format(whole_part, "0{0}b".format(bits))
else:
# Remove the sign
whole_binary = format(whole_part * -1, "0{0}b".format(bits))
# Convert the decimal part to binary
k_prec = bits
if decimal_part == 0:
decimal_binary = format(0, "0{0}b".format(k_prec))
else:
db_list = []
while k_prec > 0:
decimal_part *= 2
db_list.append(int(decimal_part))
decimal_part -= int(decimal_part)
k_prec -= 1
decimal_binary = ''.join(str(d) for d in db_list)
# Put the binary representations back together and sign (for Signed and Sign Magnitude)
binary = whole_binary + "." + decimal_binary
mag_binary = "0" + binary[1:] if num >= 0 else "1" + binary[1:]
signed_binary = binary if num >= 0 else "-" + binary
if num >= 0:
ones_binary = "n/a"
twos_binary = ""
else:
# Create an unsigned binary representation (for Complements)
raw_binary = whole_binary + decimal_binary
ones_binary = ""
# Flip bits; as chepner says, ~ doesn't work on strings
for c in raw_binary:
ones_binary += '1' if c == '0' else '0'
# Add 1 to the least significant digit
twos_binary = bin(int(ones_binary, 2) + 1)
# Format for display
ones_binary = ones_binary.replace("0b", "")
ones_binary = ones_binary[:bits] + "." + ones_binary[bits:]
twos_binary = twos_binary.replace("0b", "")
twos_binary = twos_binary[:bits] + "." + twos_binary[bits:]
return "{0:>8}\t{1:>10}\t{2}\t{3}\t{4}".format(
num, signed_binary, mag_binary, ones_binary, twos_binary)
def main():
# I am using 4 bits for readability, so I am keeping the numbers below 7
num_list = [1, 0, 0.924, -0.383, -0.5, -1, ]
print("Original\t Signed\t Sign Mag\tOne's Comp\tTwo's Comp")
for i in num_list:
print(decimal_to_binary(i, 4))
if __name__ == "__main__":
main()
输出:
Original Signed Sign Mag One's Comp Two's Comp
1.0 0001.0000 0001.0000 n/a
0.0 0000.0000 0000.0000 n/a
0.924 0000.1110 0000.1110 n/a
-0.383 -0000.0110 1000.0110 1111.1001 1111.1010
-0.5 -0000.1000 1000.1000 1111.0111 1111.1000
-1.0 -0001.0000 1001.0000 1110.1111 1111.0000
我使用RapidTables' Binary to Decimal converter and PlanetCalc's One's complement, and two's complement binary codes calculator测试了结果。
如果我有更多时间,我会把它分解成单独的功能并简化一些事情,但我把它留给你了。祝你的代码好运!
我正在尝试将正分数和负分数转换为二进制,我在网上找到了以下方法 (https://www.geeksforgeeks.org/convert-decimal-fraction-binary-number/) 将正分数转换为二进制并尝试扩展它以支持负分数。 我正在尝试对小数部分进行 2 的补码。非常感谢任何帮助。
# decimal to binary number
# Function to convert decimal to binary
# upto k-precision after decimal point
def decimalToBinary(num, k_prec) :
binary = ""
# Fetch the integral part of
# decimal number
Integral = int(num)
# Fetch the fractional part
# decimal number
fractional = num - Integral
# Conversion of integral part to
# binary equivalent
while (Integral) :
rem = Integral % 2
# Append 0 in binary
binary += str(rem);
Integral //= 2
# Reverse string to get original
# binary equivalent
binary = binary[ : : -1]
# Append point before conversion
# of fractional part
binary += '.'
# Conversion of fractional part
# to binary equivalent
while (k_prec) :
# Find next bit in fraction
fractional *= 2
fract_bit = int(fractional)
if (fract_bit == 1) :
fractional -= fract_bit
binary += '1'
else :
binary += '0'
k_prec -= 1
if (num < 0): # if negative numbers do the two's complement
binary = ~binary # struck here.
else:
binary = binary
return binary
# Driver code
if __name__ == "__main__" :
num_list=[1, 0, 0.924, -0.383]
for i in num_list:
print(i, decimalToBinary(i,8))
macky@test:~/test$ python frac_to_binary.py
(1, '1.00000000')
(0, '.00000000')
(0.924, '.11101100')
Traceback (most recent call last):
File "frac_to_binary.py", line 63, in <module>
print(i, decimalToBinary(i,8))
File "frac_to_binary.py", line 54, in decimalToBinary
binary = ~binary
TypeError: bad operand type for unary ~: 'str'
实际上有几种方法可以将二进制数显示为负数。要记住的重要一点是注意您的位大小;将您的位大小设置为大于您要转换的最大值,否则可能会发生奇怪的事情:
- bits = 4 for numbers <= 7 (
0111
) - bits = 5 for numbers <= 15 (
01111
) - bits = 8 for numbers <= 127 (
01111111
)
另一件要记住的事情是你必须转换整个二进制表示,而不是每个部分。
我修改了你的函数以显示四种类型的表示:Signed、Sign Magnitude、One's Complement,和补码:
NOTE - Tested on CentOS 7.9, using Python 2.7, and on Ubuntu 20.04, using Python 3.8
"""Program to convert rational numbers to signed and unsigned binary representations
Signed: Add a sign (0001 = 1, -0001 = -1)
Sign Magnitude: The sign is the most significant bit (0001 = 1, 1001 = -1)
One's Complement: Flip all the bits to their opposite value (0001 = 1, 1110 = -1)
Two's Complement: Flip all the bits, then add 1 to the least significant bit (0001 = 1, 1111 = -1)
Signed and decimal values checked at
https://www.rapidtables.com/convert/number/binary-to-decimal.html
Complements checked at https://planetcalc.com/747/
Warning: Set your bit size larger than the max value that you want to convert:
bits = 4 for numbers <= 7 (0111)
bits = 5 for numbers <= 15 (01111)
...
bits = 8 for numbers <= 127 (01111111)
"""
def decimal_to_binary(num, bits):
"""Function to convert rational numbers to binary representations
:param float num: The decimal to convert to binary
:param int bits: The bit size; see warning in the module docstring
:return: A formatted string with Signed, Sign Mag, One's Comp, and Two's Comp representations
:rtype: str
"""
# Ensure the number is a float
num *= 1.0
# Separate the number's components
whole_part = int(str(num).split(".")[0])
decimal_part = float("." + str(num).split(".")[1])
# Convert the whole part to binary
if whole_part >= 0:
whole_binary = format(whole_part, "0{0}b".format(bits))
else:
# Remove the sign
whole_binary = format(whole_part * -1, "0{0}b".format(bits))
# Convert the decimal part to binary
k_prec = bits
if decimal_part == 0:
decimal_binary = format(0, "0{0}b".format(k_prec))
else:
db_list = []
while k_prec > 0:
decimal_part *= 2
db_list.append(int(decimal_part))
decimal_part -= int(decimal_part)
k_prec -= 1
decimal_binary = ''.join(str(d) for d in db_list)
# Put the binary representations back together and sign (for Signed and Sign Magnitude)
binary = whole_binary + "." + decimal_binary
mag_binary = "0" + binary[1:] if num >= 0 else "1" + binary[1:]
signed_binary = binary if num >= 0 else "-" + binary
if num >= 0:
ones_binary = "n/a"
twos_binary = ""
else:
# Create an unsigned binary representation (for Complements)
raw_binary = whole_binary + decimal_binary
ones_binary = ""
# Flip bits; as chepner says, ~ doesn't work on strings
for c in raw_binary:
ones_binary += '1' if c == '0' else '0'
# Add 1 to the least significant digit
twos_binary = bin(int(ones_binary, 2) + 1)
# Format for display
ones_binary = ones_binary.replace("0b", "")
ones_binary = ones_binary[:bits] + "." + ones_binary[bits:]
twos_binary = twos_binary.replace("0b", "")
twos_binary = twos_binary[:bits] + "." + twos_binary[bits:]
return "{0:>8}\t{1:>10}\t{2}\t{3}\t{4}".format(
num, signed_binary, mag_binary, ones_binary, twos_binary)
def main():
# I am using 4 bits for readability, so I am keeping the numbers below 7
num_list = [1, 0, 0.924, -0.383, -0.5, -1, ]
print("Original\t Signed\t Sign Mag\tOne's Comp\tTwo's Comp")
for i in num_list:
print(decimal_to_binary(i, 4))
if __name__ == "__main__":
main()
输出:
Original Signed Sign Mag One's Comp Two's Comp
1.0 0001.0000 0001.0000 n/a
0.0 0000.0000 0000.0000 n/a
0.924 0000.1110 0000.1110 n/a
-0.383 -0000.0110 1000.0110 1111.1001 1111.1010
-0.5 -0000.1000 1000.1000 1111.0111 1111.1000
-1.0 -0001.0000 1001.0000 1110.1111 1111.0000
我使用RapidTables' Binary to Decimal converter and PlanetCalc's One's complement, and two's complement binary codes calculator测试了结果。
如果我有更多时间,我会把它分解成单独的功能并简化一些事情,但我把它留给你了。祝你的代码好运!