I encountered an issue with my Python script that converts binary to decimals. The caveat with this script is that I can only use basic computational functions (+, -, *, /, **, %, //), if/else, and for/while loops.
Shown below is my script:
x = int(input("Enter your binary input: "))
z=0
while x != 0:
for y in range (0,20):
if (x % 2 == 0):
z += 0*2**y
x = int(x/10)
elif (x % 2 != 0):
z += 1*2**y
x = int(x/10)
print(z)
While my script works for binaries with short length (e.g., 1101 = 13), it does not work for long binaries (especially those that have a length of 20). For example, inputting a binary of 11111010010011000111, my script returns an output of 1025217 instead of 1025223.
Can anyone point me to my mistake?
Thank you in advance!
Floating arithmetic isn't perfect and has a precision limit.
11111010010011000111 / 10 gives 1.1111010010011e+18, which when converted to an integer will give you a wrong result and it snowballs from there.
>>> int(11111010010011000111 / 10)
1111101001001100032
The more binary digits you have, the more "off" your calcuations will be.
In order to avoid the problem you encountered, use floor division, ie, x // 10.
Or you can skip turning x into a number and do the necessary power calculations based off each binary digit and its position.
x = input("Enter your binary input: ")[::-1]
n = 0
# this would be more elegant with `enumerate()`, but I assume you can't use it
# same for `sum()` and a comprehension list
for i in range(len(x)):
n += int(x[i])*2**i
print(n)
You can use the following method
to multiple each of the binary digits with its corresponding value of 2 raised to the power to its index (position from right – 1) and sum them up.
binary = input('Binary number: ')
decimal = 0
binary_len = len(binary)
for x in binary:
binary_len = binary_len - 1
decimal += pow(2,binary_len) * int(x)
print(decimal)
input : 11111010010011000111
output : 1025223
More examples
You should not use int to convert any number if you have to write a number converter.
Just use string operations:
digits = input("Enter your binary input: ")
number = 0
for digit in digits:
number = number * 2 + (digit == "1")
print(number)
output
Enter your binary input: 11111010010011000111
1025223
Related
How would I make my code round any value that has a decimal point of x.999999999?
The code so far I have is:
y = int(input("Enter a cube number "))
cuberoot = y**(1/3)
if cuberoot.is_integer():
print("integer")
else:
if cuberoot == HERE.9999999:
print("Integer")
else:
print("not integer")
help
(where it says "HERE" is what do i put there)
Use modulo operator.
y = int(input("Enter a cube number "))
cuberoot = y ** (1/3)
fraction = cuberoot % 1
if fraction == 0 or fraction > 0.999999:
print("integer")
else:
print("not integer")
Using an error-tolerance will give you incorrect results for large numbers. For example, 1012 - 1 is not a cube, but (10**12 - 1) ** (1/3) is 9999.999999996662 which would pass your test.
A safer way to do this would be to round it to an integer, then check whether it has the right cube:
def is_cube(x):
y = x ** (1/3)
y = int(round(y))
if y ** 3 == x:
print('Integer')
else:
print('Not integer')
Examples:
>>> is_cube(27)
Integer
>>> is_cube(28)
Not integer
>>> is_cube(10**12)
Integer
>>> is_cube(10**12 - 1)
Not integer
However, note that this won't work for very large numbers, since x ** (1/3) is done using floating-point numbers, so the error might be greater than 0.5, in which case the rounding will give the wrong result. For example, the above code fails for the input 10 ** 45.
So I am meant to write a program that will convert a decimal to a binary and then another that will do the opposite. I know there are python functions to do this, but I think we are meant to do it the longer way. The pseudocode goes like this:
Decimal to Binary:
number = Prompt user for input, convert to int
Set quotient equal to number, remainder equal to zero
while(number!=0)
(quotient,remainder)=divmod(quotient,2)
print(remainder)
Binary to Decimal
number=Prompt user for input
Get string length of number = n
for x in range(n)
sum+=(2^n) times x
print sum
Any help?
Codes for manually converting. Am using loops here. It can be done using recursion too.
#Binary to Decimal
def btod(binary):
decimal = 0
for digit in binary:
decimal = decimal*2 + int(digit)
return decimal
#Decimal to Binary
def dtob(decimal):
if decimal == 0:
return 0
binary=''
decimal = int(decimal) #incase arg is int
while (decimal > 0):
binary+= str(decimal%2)
decimal = int(decimal/2)
return binary[::-1] #reverse the string
print(btod('101'))
#5
print(dtob('5'))
#101
The translation dictionary for your pseudo-code:
"Prompt user for input, convert to int":
int(input("Enter a decimal number: "))
"Set quotient equal to number, remainder equal to zero":
quotient = number
remainder = 0
"divmod(quotient,2)":
quotient // 2, quotient % 2
"Prompt user for input":
input("Enter a binary number: ")
"Get string length of number = n":
n = len(number)
"(2^n) times x":
2**n * x
"print sum":
print(sum)
Use this dictionary for replacing the corresponding parts in your pseudo-code. All other parts keep in their place, including indentations.
Note:
By your pseudo-code your program "Decimal to Binary" will print the converted decimal number in the column - read the result from bottom to top.
I have made a Python 3 program to calculate pi for a school project, but it always stops at 16 decimal places. Is there a limit to the length of numbers in python? If so is there a language that I could use that will let me continue?
accuracy = int(input("accuracy: "))
current = 2
opperation = "+"
number = 3
count = 1
for i in range (accuracy):
if opperation == "-":
number = number - (4/(current*(current+1)*(current+2)))
opperation = "+"
elif opperation == "+":
number = number + (4/(current*(current+1)*(current+2)))
opperation = "-"
current += 2
print(str(count).zfill(8)) + ": " + str(number)
count += 1
There is no restriction if you are working with integers and Python 3.x. The precision you get using floating point numbers is however limited. A Python float (like 3.14) is really a C double, which have about 16 decimals of precision, as you say.
You can use the decimal module to create and work with other floating point numbers with arbitrary precision. Example code:
# Normal Python floats
a = 0.000000000000000000001
b = 1 + 2*a
print(b) # Prints 1.0
# Using Decimal
import decimal
decimal.getcontext().prec = 100 # Set the precision
a = decimal.Decimal('0.000000000000000000001')
b = 1 + 2*a
print(b) # Prints 1.000000000000000000002
See the docs for more information on decimal.
I am a complete beginner to Python. I wrote some code to perform base conversion and I was wondering if there were better alternatives that were shorter to code (one-liners) or significantly faster. The code looks ugly and feels "non-Pythonic" though being a beginner I should not have any such opinion. Any feedback to improve the code would be appreciated. This is purely for learning purposes.
#!/usr/bin/env python
import math
def number_to_digits( number, radix ):
'Converts a number into a vector of digits in given radix'
digits = [0]*int(math.ceil(math.log(number,radix)))
for ii in range(len(digits)):
(number,digit) = divmod(number,radix)
digits[ii] = digit
return digits
def digits_to_number( digits, radix ):
'Converts a vector of non-negative digits in given radix into a number'
number = 0;
for ii in range(len(digits)-1,-1,-1):
number *= radix
number += digits[ii]
return number
if __name__ == '__main__':
try:
number = int(raw_input('Enter number: '))
if number <= 0: raise ValueError()
radix = int(raw_input('Enter radix: '))
if radix <= 0: raise ValueError()
digits = number_to_digits(number,radix)
print digits
number_again = digits_to_number(digits,radix)
if not number_again == number:
print 'test failed'
except ValueError:
print 'unexpected input'
A sample session on the terminal produces:
Enter number: 44
Enter radix: 6
[2, 1, 1]
It is easy to check that 2 + 1*6 + 1*6**2 == 44. Thanks!
Here's a nice recursive version that will convert up to hexadecimal from Problem Solving with Algorithms and Data Structures
def toStr(n,base):
convertString = "0123456789ABCDEF"
if n < base:
return convertString[n]
else:
return toStr(n//base,base) + convertString[n%base]
print(toStr(1453,16))
Python provides some built-in functions to convert a value represented in one Integer base to another Integer base. Integer is represented in four forms i.e. decimal, binary, octal, and hexadecimal form.
Python provides built-in bin() functions to convert from non-binary number to binary number, oct() function to convert from non-octal number to octal number and hex() function to convert from non-hexadecimal number to hexadecimal number. These functions return a string literal to represent the values.
You can learn these functions from the tutorial on Integer base Conversion Functions in Python
You can find (slightly) cleaner example in the following thread:
Python elegant inverse function of int(string,base).
Taking the top ranked example, you can clean it up a bit to:
def digit_to_char(digit):
if digit < 10:
return str(digit)
return chr(ord('a') + digit - 10)
def str_base(number, base):
while number > 0:
number, digit = divmod(number, base)
yield digit_to_char(digit)
Results in:
>>> list(str_base(44, 6))
['2', '1', '1']
If you don't care about bases larger than 10, it simplifies to:
def str_base(number, base):
if base > 10:
raise ValueError('Base must be less than 10')
while number > 0:
number, digit = divmod(number, base)
yield digit
>>> list(str_base(44, 6))
[2, 1, 1]
decimal = input("Please insert a number: ")
if decimal > 256:
print "Value too big!"
elif decimal < 1:
print "Value too small!"
else:
decimal % 2
binary1 = []
binary0 = []
if decimal % 2 == 0:
binary1.append[decimal]
else:
binary0.append[decimal]
print binary1
print binary0
So Far, I want to test this code, it says on line 13:
TypeError: builtin_function_or_method' object has no attribute
__getitem__.
I don't understand why it is wrong.
I would like to convert the decimal number into binary. I only wanted to try and get the first value of the input then store it in a list to use then add it to another list as either a 0, or a 1. And if the input doesn't divide by 2 equally, add a zero. How would I do this?
binary1.append[decimal]
You tried to get an element from the append method, hence triggering the error. Since it's a function or method, you need to use the appropriate syntax to invoke it.
binary1.append(decimal)
Ditto for the other append call.
In response to your binary question. It is possible to brute-force your way to a solution quite easily. The thinking behind this is we will take any number N and then subtract N by 2 to the biggest power that will be less than N. For instance.
N = 80
2^6 = 64
In binary this is represented as 1000000.
Now take N - 2^6 to get 16.
Find the biggest power 2 can be applied to while being less than or equal to N.
2^4 = 16
In binary this now represented as 1010000.
For the actual code.
bList = []
n = int(raw_input("Enter a number"))
for i in range(n, 0, -1): # we will start at the number, could be better but I am lazy, obviously 2^n will be greater than N
if 2**i <= n: # we see if 2^i will be less than or equal to N
bList.append(int( "1" + "0" * i) ) # this transfers the number into decimal
n -= 2**i # subtract the input from what we got to find the next binary number
print 2**i
print sum(bList) # sum the binary together to get final binary answer