How to convert binary to decimal using a for loop? - python

I don't quite understand what I am doing wrong as I started learning Python 4 days back. I want to do this using for loop to convert binary number into decimal number.
def binary_to_decimal(number):
i, integer = 0, 0
size = list(number)
for value in size:
integer = int(size[i]) * pow(2, i)
i += 1
print(f"the decimal representation is {integer}")
def binary_to_decimal("111")
The output I am getting is 3 not 4.

You need to aggregate your variable integer using += instead of =
def binary_to_decimal(number):
i, integer = 0, 0
size = list(number)
for value in size:
integer += int(size[i]) * pow(2, len(size)-1-i)
i += 1
print(f"the decimal representation is {integer}")
>>> binary_to_decimal("111")
the decimal representation is 7
>>> bin(7)
'0b111'

Related

positive and negative fraction to binary conversion

I am trying to convert positive and negative fractions to binary, I found the following approach online (https://www.geeksforgeeks.org/convert-decimal-fraction-binary-number/) to convert positive fractions to binary and tried to extend it to support the negative fractions.
I am trying to do the 2's complement on the fractional part. Any help is much appreciated.
# 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'
There are actually a few ways to display binary numbers as negatives. The important thing to remember is to watch your bit size; set your bit size larger than the max value that you want to convert, or weird things may happen:
bits = 4 for numbers <= 7 (0111)
bits = 5 for numbers <= 15 (01111)
bits = 8 for numbers <= 127 (01111111)
Another thing to remember is that you have to convert the whole binary representation, not each part.
I modified your function to display four types of representations: Signed, Sign Magnitude, One's Complement, and Two'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()
Output:
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
I tested the results using RapidTables' Binary to Decimal converter and PlanetCalc's One's complement, and two's complement binary codes calculator.
If I had more time, I would break this up into separate functions and streamline a few things, but I leave that up to you. Good luck with your code!

How can I fix not all arguments converted during string formatting?

I want to change some binary streams to decimal but I got not all arguments converted during string formatting. The point is I have the result when using binaryToDecimal (10100000) which 10100000 is the first value of my list. But when I use binaryToDecimal (instream_chunks[0]) which is my for loop I got the above error. How can I fix that?
I am new to python sorry for my simple question.......
def binaryToDecimal(binary):
binary1 = binary
decimal, i, n = 0, 0, 0
while(binary != 0):
dec = binary % 10
decimal = decimal + dec * pow(2, i)
binary = binary//10
i += 1
print(decimal)
instream = '1010000000011000000110000000001'
instream_chunks = [instream[i:i+8]for i in range (0, len(instream), 8)]
for i in range (len(instream_chunks)):
img_value = binaryToDecimal (instream_chunks[i])
You need to convert the strings to integers before using your function on them. Like so:
def binaryToDecimal(binary):
binary1 = binary
decimal, i, n = 0, 0, 0
while(binary != 0):
dec = binary % 10
decimal = decimal + dec * pow(2, i)
binary = binary//10
i += 1
print(decimal)
instream = '1010000000011000000110000000001'
instream_chunks = [instream[i:i+8]for i in range (0, len(instream), 8)]
for i in range (len(instream_chunks)):
img_value = binaryToDecimal (int(instream_chunks[i]))

How can I print E number to high n precision? Using my own value

Here is my code:
E = 2.7182818284590452353602875
n = int(input())
print(round(E,n))
For example, I need to round this to 24 decimal
But it`s gives just:
E = 2.71828182845
#No more
How to fix this?
Do not use Python float for this task because it will lose numbers due to precision. Use decimal module:
from decimal import Decimal
E = Decimal('2.7182818284590452353602875')
n = int(input())
print(E.quantize(Decimal('1.' + '0' * n)))
Output:
2.718281828459045235360288
As ingvar mentions the decimal module is necessary to get this level of precision. That said, you can also let it do the work of generating e in the first place via the exp recipe included in the docs, so you don't have to hardcode a specific value:
from decimal import localcontext, Decimal
def exp(x):
"""Return e raised to the power of x. Result type matches input type.
>>> print(exp(Decimal(1)))
2.718281828459045235360287471
>>> print(exp(Decimal(2)))
7.389056098930650227230427461
>>> print(exp(2.0))
7.38905609893
>>> print(exp(2+0j))
(7.38905609893+0j)
"""
with localcontext() as ctx:
ctx.prec += 2
i, lasts, s, fact, num = 0, 0, 1, 1, 1
while s != lasts:
lasts = s
i += 1
fact *= i
num *= x
s += num / fact
return +s
n = int(input())
with localcontext() as ctx:
ctx.prec = n + 1 # Use exactly the precision needed (one more than requested as 2 counts)
print(exp(Decimal(1)))
which, given an input of 24, outputs:
2.718281828459045235360287
Try it online!

Convert binary string into two's complement

For our homework assignemnt, we are asked to take in an integer and return the two's complement of it.
Currently, I am able to convert the integer into a binary string. From there, I know I need to invert the 0's and 1's and add 1 to the new string, but I do not know how to do that.
Could someone help me with that please?
def numToBinary(n):
'''Returns the string with the binary representation of non-negative integer n.'''
result = ''
for x in range(8):
r = n % 2
n = n // 2
result += str(r)
result = result[::-1]
return result
def NumToTc(n):
'''Returns the string with the binary representation of non-negative integer n.'''
binary = numToBinary(n)
# stops working here
invert = binary
i = 0
for digit in range(len(binary)):
if digit == '0':
invert[i] = '1'
else:
invert[i] = '0'
i += 1
return invert
Note: This is an intro level course, so we are mainly stuck to using loops and recursion. We cannot really use any fancy formatting of strings, built-in functions, etc. beyond the basics.
I was able to reach my solution by doing the following:
def numToBinary(n):
'''Returns the string with the binary representation of non-negative integer n.'''
result = ''
for x in range(8):
r = n % 2
n = n // 2
result += str(r)
result = result[::-1]
return result
def NumToTc(n):
'''Returns the string with the binary representation of non-negative integer n.'''
binary = numToBinary(n)
for digit in binary:
if int(digit) < 0:
binary = (1 << 8) + n
return binary

How to convert between floats and decimal twos complement numbers in Python?

I want to convert decimal float numbers in python into twos complement decimal binary numbers. For example 1.5 in twos complement decimal 2.6 (8 bits) would be 0b011000.
Is there a module that can do this for me?
What you're describing has nothing at all to do with decimal. You want to convert a float to a fixed-point binary representation. To do this, you would multiply the float by a scale factor, cast it to an integer, and use Python's built-in string formatting tools to get the string representation:
def float_to_binary(float_):
# Turns the provided floating-point number into a fixed-point
# binary representation with 2 bits for the integer component and
# 6 bits for the fractional component.
temp = float_ * 2**6 # Scale the number up.
temp = int(temp) # Turn it into an integer.
# If you want -1 to display as 0b11000000, include this part:
# if temp < 0:
# temp += 2**8
# The 0 means "pad the number with zeros".
# The 8 means to pad to a width of 8 characters.
# The b means to use binary.
return '{:08b}'.format(temp)
Well, I couldnt find anything so I wrote some code and tested it.Should work...
def floatToTwosComplementDecimal(intBits,decBits,number):
if decBits == 0:
mx = pow(2,intBits-1) - 1 # maximum number
else:
mx = pow(2,intBits-1) - pow(2,-1*decBits) # maximum number
mn = -1*pow(2,intBits-1) # minimum number
if number > mx:
print "number:" + str(number) + " has been truncated to: " + str(mx)
number = mx
elif number < mn:
print "number:" + str(number) + " has been truncated to: " + str(mn)
number = mn
n = []
m = 0
if number < 0:
n.append(1)
m = -1*pow(2,intBits-1)
else:
n.append(0)
m = 0
for i in reversed(range(intBits-1)):
m1 = m + pow(2,i)
if number < m1:
n.append(0)
else:
n.append(1)
m = m1
for i in range(1,decBits+1):
m1 = m + pow(2,-1*i)
if number < m1:
n.append(0)
else:
n.append(1)
m = m1
return string.join([str(i) for i in n], '')
def twosComplementDecimalToFloat(intBits,decBits,binString):
n = 0.0
if binString[0] == "1":
n = -1*pow(2,intBits-1)
for i in range(intBits-1):
n += int(binString[intBits-1-i])*pow(2,i)
for i in range(1,decBits+1):
n += int(binString[intBits-1+i])*pow(2,-1*i)
return n
You can use the Binary fractions package. This package implements TwosComplement with binary integers and binary fractions. You can convert binary-fraction strings into their twos complement and vice-versa
Example:
>>> from binary_fractions import TwosComplement
>>> str(TwosComplement(-1.5)) # float --> TwosComplement
'10.1'
>>> str(TwosComplement(1.5)) # float --> TwosComplement
'01.1'
>>> TwosComplement.to_float("11111111111") # TwosComplement --> float
-1.0
>>> TwosComplement.to_float("11111111100") # TwosComplement --> float
-4.0
>>> str(TwosComplement(5)) # int --> TwosComplement
'0101'
To use this with Binary's instead of float's you can use the Binary class inside the same package.
PS: Shameless plug, I'm the author of this package.

Categories