Converting Binary to Decimal in python (without built in binary function) - python

Alrighty, first post here, so please forgive and ignore if the question is not workable;
Background:
I'm in computer science 160. I haven't taken any computer related classes since high school, so joining this class was a big shift for me. It all seemed very advanced. We have been working in Python and each week we are prompted to write a program.
I have been working with this problem for over a week and am having a hard time even starting.
The prompt is to read an integer containing only 1's and 0's,
process the binary number digit by digit and report the decimal equivalent. Now, I have gotten some tips from a classmate and it sent me at least in a direction.
Set up a couple of counters;
using the % operator to check the remainder of the number divided by 2, and slicing off the last number (to the right) to move on to and process the next digit.
I am having an incredibly hard time wrapping my head around what formula to use on the binary digits themselves which will convert the number to decimal.
setbitval = 0
counter = 0
user = int(input("enter a binary value. "))
if user % 2 == 1:
user = (user/10) - .1
setbitval += 1
This is all I've got so far.. My thinking is getting in the way. I've searched and searched, even through these forums.
Any information or thoughts are extremely appreciated,
T
Edit: okay guys, everyone's help has been extremely useful but I'm having a problem checking if the user input is not a binary number.
for i in reversed(bits):
decimal += 2**counter * int(i)
counter += 1
This is the formula someone here gave me and I've been trying different iterations of "for i in bits: if i in bits: != 0 or 1" and also "if i in bits: >= 1 or <=0".
Any thoughts?

you can use this code:
binary= raw_input("Binary: ")
d= int(binary, 2)
print d

To convert binary value to decimal you need to do the following:
Take the least significant bit and multiply it by 2^0, then take the next least significant beat and multiply it by 2^1, next one by 2^2 and so on...
Let's say, for example you need to convert a number 1010 to decimal:
You would have 0*2^0 + 1*2^1 + 0*2^2 + 1*2^3 = 0 + 2 + 0 + 8 = 10
So in your python code, you need to:
read the int that the user inputted (representing the binary value).
convert that int and convert it to string, so you can break it into list of digits
make a list of digits from the string you created (a list int python can be created from a string not an int, that's why you need the conversion to string first)
go trough that list of bits in reverse and multiply every bit by 2^k, k being the counter starting from 0
Here's the code that demonstrates what I just tried to explain:
user_input = int(input("enter a binary value"))
bits = list(str(user_input))
decimal = 0
counter = 0
for i in reversed(bits):
decimal += 2**counter * int(i)
counter+=1
print 'The decimal value is: ', decimal

I'll agree this is close to the "code this for me" territory, but I'll try to answer in a way that gets you on the right track, instead of just posting a working code snippet.
A simple way of doing this is just to use int()'s base argument, but I'm guessing that is disallowed.
You already have a way of testing the current bit in your question, namely checking whether n % 2 == 1. If this is the case, we need to add a power of two.
Then, we need some way of going to the next bit. In binary, we would use bit shifts, but sadly, we don't have those. a >> b is equivalent to a // (2**b) - can you write a decimal equivalent to that?
You also need to keep a counter of which power of two the current bit represents, a loop, and some way of detecting an end condition. Those are left as exercises to the reader.

I’d recommend reading the following articles on Wikipedia:
https://en.wikipedia.org/wiki/Radix
https://en.wikipedia.org/wiki/Binary_number
The first one gives you an idea how the numeral systems work in general and the second one explains and shows the formula to convert between binary and decimal systems.
Try to implement the solution after reading this. That’s what I did when I dealt with this problem. If that doesn’t help, let me know and I’ll post the code.
Hopefully, this code clarifies things a bit.
x = input("Enter binary number: ").strip()
decimal = 0
for i in range(len(x)):
decimal += int(x[i]) * 2**abs((i - (len(x) - 1)))
print(decimal)
This code takes in a binary number as a string, converts it to a decimal number and outputs it as an integer. The procedure is the following:
1st element of binary number * 2^(length of binary number - 1)
2nd element of binary number * 2^(length of binary number - 2)
and so on till we get to the last element and ...2^0
If we take number 10011, the conversion using this formula will look like this:
1*2^4 + 0*2^3 + 0*2^2 + 1*2^1 + 1*2^0, which equals to 19.
This code, however, assumes that the binary number is valid. Let me know if it helps.
Another implementation using while loop might look like this. Maybe it'll be easier to understand than the code with the for loop.
x = input("Enter binary number: ").strip()
decimal = 0
index = 0
exp = len(x) - 1
while index != len(x):
decimal += int(x[index]) * 2**exp
index += 1
exp -= 1
print(decimal)
In this one we start from the beginning of the number with the highest power, which is length of binary number minus one, we loop through the number, lowering the power and changing index.
Regarding checking if number is binary.
Try using helper function to determine if number is binary and then insert this function inside your main function. For example:
def is_binary(x):
""" Returns True if number x is binary and False otherwise.
input: x as a string
"""
for i in list(x):
if i not in ["1", "0"]:
return False
return True
def binary_decimal(x):
""" Converts binary to decimal.
input: binary number x as a string
output: decimal number as int
"""
if not is_binary(x):
return "Number is invalid"
decimal = 0
for i in range(len(x)):
decimal += int(x[i]) * 2**abs((i - (len(x) - 1)))
return decimal
The first function checks if number consists only of ones and zeros and the second function actually converts your number only if it's binary according to the first function.
You can also try using assert statement or try / except if you'd better raise an error if number is not binary instead of simply printing the message.
Of course, you can implement this solution without any functions.

Related

Python not returning all the zeros but e-n

I have a python code that when given a small number between 0 and 1 doesn't print it fully, but 4.43017984825e-7 for example,how do I make the code shows the whole number with all zeroes?
this was my try:
number="4.43017984825e-7"
result=number.find("e")
new=list(number)
last=int(new[-1])
print(last)
del new[13:16]
print(new)
pricee=(''.join(new))
print(pricee)
price=float(pricee)*10**-(last)
print(price)
Note: the number changes everytime, so I want it to be applicable for all numbers.
You can probably accomplish what you want with fixed-point formatting.
>>> x=4.43017984825e-7
>>> print(x)
4.43017984825e-07
>>> print(f"{x:20.18f}")
0.000000443017984825
The 20 in that format tells the full width you want, while the 18 tells the number of decimals.
Now, this is fairly specific to this number, you'll have to pick the right length and number of decimals for your actual application.
Expanding on the suggestion from #MostafaFarzán: you can use log10 to adjust that fixed point formatting to any number:
x = <some float>
significant_digits = 8
decimals=max(0, int(-log10(x) + significant_digits))
print(f"%.{decimals}f" % x)
or, more concisely but harder to read:
print(f"%.{max(0, int(-log10(x) + 8))}f" % x)

Python print questions related to float

print("%.5f" % 5.1234567890) output is 5.12346
i am not understanding why 5 is not printed in output in precision field. after 4 the 6 is printed directly. why?
You limit the number of digits in fractional part to 5 digits. When you do that it rounds the number up or down based on number after the last digit. In your case, the fifth digit of the fractional part is 5 and after that is 6. So it rounds the number 5 up.
The number you type after the dot limits the float digits after the decimal point. so your command will prints the number and the first 5 digits of his decimal part.
I don't think there is anything in the math library to do this, since obviously normal people would round that number up.
But if you are really trying to round down, for whatever reason, you would need to build a function or import some other library someone else made to do it.
You can also create a function do it, for example:
import math
def round_decimals_down(number:float, decimals:int=2):
if not isinstance(decimals, int):
raise TypeError("A")
elif decimals < 0:
raise ValueError("B")
elif decimals == 0:
return math.floor(number)
factor = 10 ** decimals
return math.floor(number * factor) / factor
valueA = 5.1234567890
roundA = round_decimals_down(valueA, 5)
print(roundA)
output: 5.12345
Let me know if that is what you were trying to accomplish.

int(str) of a huge number

if i have a number that is too big to be represented with 64 bits so i receive a string that contains it.
what happens if i use:
num = int(num_str)
i am asking because it looks like it works accurately and i dont understand how, does is allocate more memory for that?
i was required to check if a huge number is a power of 2. someone suggested:
def power(self, A):
A = int(A)
if A == 1:
return 0
x =bin(A)
if x.count('1')>1:
return 0
else:
return 1
while i understand why under regular circumstances it would work, the fact that the numbers are much larger than 2^64 and it still works baffles me.
According to the Python manual's description on the representation of integers:
These represent numbers in an unlimited range, subject to available (virtual) memory only. For the purpose of shift and mask operations, a binary representation is assumed, and negative numbers are represented in a variant of 2’s complement which gives the illusion of an infinite string of sign bits extending to the left.

Converting a calculated decimal number into 8 bit binary

I am currently making a python program that is byte adder related, it will prompt the user to enter 2 integers, add them together and if it's within the range of the actual size of a byte (0 to 255) display that number and also give the corresponding value in its 8 bit binary form, for example, the calculation is equal to 1, show the binary number which python declares as the correct one.
This is the task that I am doing ~
"The program must check the input data for the data type permitted and the data value limitations (the value of the integer must not exceed the actual size of byte-coded integers, i.e. min 00000000 and max 11111111 in Base 2 or min 0 and max 255 in Base 10 for positive integers" Input in both binary and decimal format with conversion to binary
def add():
Num1 = int(input("Input the first number between 0 and 255, the calculated answer must not be above 255: "))
Num2 = int(input("Input the second number between 0 and 255, the calculated answer must not be above 255: "))
calculatedanswer = Num1+Num2
if calculatedanswer >= 0 and calculatedanswer <=255:
print("The answer in decimal is" ,calculatedanswer,)
**bin(calculatedanswer)**
elif calculatedanswer < 0 and calculatedanswer >255:
print("Please ensure the added numbers are above 0 and below 255")
add()
This is my code so far, I have no trouble getting it to display the standard decimal number, but I really can't get the bin(calculatedanswer) to show the binary equivalent of it. I tried using this method that I found on YouTube.
I think my main problem here is my lack of understanding of how "bin" works on python as this is really the first time I am using it.
I have put asterisks around the line that I am having trouble with.
You do have to print the value:
>>> print(bin(160)) # This version gives the 0b prefix for binary numbers.
0b10100000
>>> print(format(160,'08b')) # This specifies leading 0, 8 digits, binary.
10100000
>>> print('{:08b}'.format(160)) # Another way to format.
10100000
>>> print(f'{160:08b}') # Python 3.6+ new f-string format.
10100000
One option for printing it would be to slice off the 0b portion of the result, which I assume is what you mean when you say you are having problems with the bin function.
Try this:
print(bin(calculatedanswer)[2:]))

Solving recursive sequence

Lately I've been solving some challenges from Google Foobar for fun, and now I've been stuck in one of them for more than 4 days. It is about a recursive function defined as follows:
R(0) = 1
R(1) = 1
R(2) = 2
R(2n) = R(n) + R(n + 1) + n (for n > 1)
R(2n + 1) = R(n - 1) + R(n) + 1 (for n >= 1)
The challenge is writing a function answer(str_S) where str_S is a base-10 string representation of an integer S, which returns the largest n such that R(n) = S. If there is no such n, return "None". Also, S will be a positive integer no greater than 10^25.
I have investigated a lot about recursive functions and about solving recurrence relations, but with no luck. I outputted the first 500 numbers and I found no relation with each one whatsoever. I used the following code, which uses recursion, so it gets really slow when numbers start getting big.
def getNumberOfZombits(time):
if time == 0 or time == 1:
return 1
elif time == 2:
return 2
else:
if time % 2 == 0:
newTime = time/2
return getNumberOfZombits(newTime) + getNumberOfZombits(newTime+1) + newTime
else:
newTime = time/2 # integer, so rounds down
return getNumberOfZombits(newTime-1) + getNumberOfZombits(newTime) + 1
The challenge also included some test cases so, here they are:
Test cases
==========
Inputs:
(string) str_S = "7"
Output:
(string) "4"
Inputs:
(string) str_S = "100"
Output:
(string) "None"
I don't know if I need to solve the recurrence relation to anything simpler, but as there is one for even and one for odd numbers, I find it really hard to do (I haven't learned about it in school yet, so everything I know about this subject is from internet articles).
So, any help at all guiding me to finish this challenge will be welcome :)
Instead of trying to simplify this function mathematically, I simplified the algorithm in Python. As suggested by #LambdaFairy, I implemented memoization in the getNumberOfZombits(time) function. This optimization sped up the function a lot.
Then, I passed to the next step, of trying to see what was the input to that number of rabbits. I had analyzed the function before, by watching its plot, and I knew the even numbers got higher outputs first and only after some time the odd numbers got to the same level. As we want the highest input for that output, I first needed to search in the even numbers and then in the odd numbers.
As you can see, the odd numbers take always more time than the even to reach the same output.
The problem is that we could not search for the numbers increasing 1 each time (it was too slow). What I did to solve that was to implement a binary search-like algorithm. First, I would search the even numbers (with the binary search like algorithm) until I found one answer or I had no more numbers to search. Then, I did the same to the odd numbers (again, with the binary search like algorithm) and if an answer was found, I replaced whatever I had before with it (as it was necessarily bigger than the previous answer).
I have the source code I used to solve this, so if anyone needs it I don't mind sharing it :)
The key to solving this puzzle was using a binary search.
As you can see from the sequence generators, they rely on a roughly n/2 recursion, so calculating R(N) takes about 2*log2(N) recursive calls; and of course you need to do it for both the odd and the even.
Thats not too bad, but you need to figure out where to search for the N which will give you the input. To do this, I first implemented a search for upper and lower bounds for N. I walked up N by powers of 2, until I had N and 2N that formed the lower and upper bounds respectively for each sequence (odd and even).
With these bounds, I could then do a binary search between them to quickly find the value of N, or its non-existence.

Categories

Resources