Printing binary without trailing 0s? [duplicate] - python

This question already has answers here:
Why does integer division yield a float instead of another integer?
(4 answers)
Closed 4 months ago.
Trying to create a small program that takes in positive integers and converts it into reverse binary.
I've gotten this far:
import math
integer = int(input())
while integer > 0:
x = integer % 2
print(int(math.floor(x)), end='')
integer = integer / 2
The problem with this is that the output would have unnecessary trailing 0s. For example, if the input is 12, the output would be 0011000......
I've tried the int function to remove floats, I also tried floor function to round up(albeit I might've done it wrong).
Could the problem be a lack of sentinel value?

It sounds like you have reversed a binary number like this:
def reverse_bits(n):
res = 0
for i in range(n.bit_length(), -1, -1):
if n & (1 << i):
res += 1 << (n.bit_length() - i)
return res
bin(reverse_bits(12)) # '0b110'
You can bit shift to the right, until there is a 1 in the rightmost bit, to remove trailing zeros:
def remove_trailing_zeros(n):
while not n & 1:
n = n >> 1
return n
All together:
bin(remove_trailing_zeros(reverse_bits(12)))
Out[11]: '0b11'

use // instead of / in division

Here is an alternate approach:
integer = 3
print (bin(integer)[2:][::-1])

Related

Calculating needed padding size to have a bit string having length which is a multiple of 8 [duplicate]

This question already has answers here:
How to make sure the input is a multiple of 16, and if not add padding to it
(2 answers)
Closed 12 months ago.
def asn1_integer(i):
if i >= 0:
i = decimal_to_binary(i)
if len(i) < 8:
i = ('0'* (8 - len(i))) + i
I want the length of i to be a multiple of 8. So I need to have a function that adds '0's to the beginning of a bit string, relative to the 8k - len(i) = number_of_additional_bits equation.
P.s. bin, hex, str, int, bytearray, divmod functions are prohibited for this task.
decimal_to_binary(i) converts a decimal to binary equivalent by using the bitwise operators.
It's trivial to figure out the next multiple of 8 that's greater than your string's length. Use divmod to divide the current length by 8. If there's a remainder, your final string needs to be of a length (quotient + 1) * 8. If there isn't a remainder, you just need quotient * 8
i = "11001"
str_len = len(i)
req_len, remainder = divmod(str_len, 8)
if remainder: req_len += 1
req_len *= 8
Then, pad your string to req_len:
i = f'{i:>0{req_len}}' # '00011001'
The f'...' construct is called a f-string and is an easy way to do string interpolation. More info

Python while loop not working as intended

I don't know how to get over this problem with while loop.
So basically I want to return the number of zeros at the end of a number's factorial.
import math
def zeros(n):
total_zero = 0
n = math.factorial(n)
while str(n)[-1] == '0': # to check if the last number is 0 or not
n = n * 0.1
total_zero += 1
return total_zero
output = zeros(30)
print(output)
After the while loop runs only 1 time, it breaks; I don't know why.
Help would be very appreciated. Thanks!
After multiplying your value by 0.1 it becomes a float, and it's string representation becomes the scientific notation 2.6525285981219107e+31 which doesn't end by a 1
You'd better do the integer division by 10 to keep an int
def zeros(n):
total_zero = 0
n = math.factorial(n)
while str(n)[-1] == '0': # to check if the last number is 0 or not
n = n // 10
total_zero += 1
print(f"testting {str(n)}")
return total_zero
>> zeros(30)
testting 26525285981219105863630848000000
testting 2652528598121910586363084800000
testting 265252859812191058636308480000
testting 26525285981219105863630848000
testting 2652528598121910586363084800
testting 265252859812191058636308480
testting 26525285981219105863630848
7
Better You can also use str.rstrip : you remove the leading zeros and check the length difference
def zeros(n):
value = str(math.factorial(n))
return len(value) - len(value.rstrip("0"))
My first answer above was literally solving the question that the user asked: "Why doesn't my code work?" But there is a much much simpler way of solving the question "How many zeros does n! have at the end" which is so simple you can do the math in your head.
Look at the prime factorization of any number f. To get a "0" at the end of a number, you must have 2 x 5 in the prime factorization. So the number of zeros at the end of f is just the minimum of the number of 2s and the number of 5s in the prime factorization. For factorials, you always get more factors of 2 than of 5, so we're down to the question: How many 5s are there in the prime factorization of n!
That's easy! Legendre's formula says it is:
floor(n/5) + floor(n/25) + floor(n/125) + ...
and although this is an infinite series, after a couple of terms, they're all zero. For 30!, you get 6 + 1 + 0 + 0 + ... = 7.
If asked how many 0s there are at the end of 1000!, the answer is `200 + 40 + 8 + 1 = 249'
Why didn't you bother to do any debugging? See this lovely debugging site for help. A simple print to trace n shows the problem.
You're doing a float computation on an integer; the result you get back is not guaranteed to be exact. Instead, use
n = n // 10
After you multiply by .1, you have a floating point number. You will be losing precision with a number as large as 30! You want to divide by 10 using //.
Also rather than looking at the last digit in the string, you can just look at the number mod 10. Much faster
In python, the * operator on an int and float outputs a float. Casting to str converts long floats into scientific notation. Therefore on your second iteration you have:
> str(math.factorial(30)*.1)
'2.6525285981219107e+31'
> str(math.factorial(30)*.1)[-1]
'1'
Since math.factorial always returns an int, which str converts to a string of the full integer value, you might try first converting the output of math.factorial to a string, and then iterating backward through that string. Something like:
def count_zeros(n):
count = 0
n = str(math.factorial(n))
while n[-1] == '0':
count += 1
n = n[:-1]
return count
This could be solved a bit more compactly as follows
from math import factorial
from itertools import takewhile
def zeros(n):
return sum(1 for _ in takewhile(lambda i: i == '0', reversed(str(factorial(n)))))
For example
>>> zeros(30)
7
This basically computes the factorial, converts that to a string, then counts the '0' characters from the string backwards until it encounters a non-zero character.

Decimal to Binary number conversion program -- How to make it better or shroter? [duplicate]

This question already has answers here:
Python int to binary string?
(36 answers)
Closed 2 years ago.
I am a beginner in python. I have written a program to convert decimal numbers to binary. It works. But Is there any other way to make it better? Refer to my code. Thanks :)
def decimal_to_binary_converter(dec):
print(f"Decimal: {dec}")
binary = ""
# Using while loop dividing the decimal number by 2 and concatenating the reminder to the string variable "binary" .
# % Operator gets the reminder from the division.
while int(dec) > 0:
binary += str(int(dec)%2)
dec = int(dec) / 2
x = int(len(binary))
rev_binary = ""
# using this while loop reversing the string "binary" and showing the Output.
while x > 0:
rev_binary += str(binary[x-1])
x -= 1
return print(f"Binary: {rev_binary}")
decimal_to_binary_converter(945)
Output:
Decimal: 945
Binary: 1110110001
You can get it in one line
n = int(input())
binaryNo = bin(n).replace("0b","")

A function that takes in a string of numbers and returns the integer without the use of the built-in int() function [duplicate]

This question already has answers here:
Convert String to Int without int()
(4 answers)
Closed 2 years ago.
I need to create a function that takes in a string e.g. '142' and return it as an integer, without the use of the int() function. I'm not sure where to start at all and the 'hint' provided to us is to use a list such as
digits = list('0123456789')
edit: We have not yet learnt chr, ord, eval() or ast.literal_eval? We have not yet learnt what string and integer literals are nor have we learnt dictionaries. for loops as well as 'in' are discouraged as well.
Does anyone have any ideas as to how to approach this?
From '5768' you can get 8 * 1 + 6 * 10 + 7 * 100 + 5 * 1000. You can use a loop to access the characters of the string and you have to keep track of the multiplier.
index can be used to find the position of the current character in the list and then you have the correct integer value for multiplication.
digits = list('0123456789')
value = 0
exp = 0
for c in reversed('5768'):
print(f'c={c} exp={exp}')
i = digits.index(c)
value += i * 10 ** exp
exp += 1
print(value)
After getting some more constraints in the question this code can be adjusted to the following.
digits = list('0123456789')
number = '5768'
value = 0
character_position = 0
while character_position < len(number):
i = digits.index(number[character_position])
value += i * 10 ** (len(number) - character_position - 1)
character_position += 1
print(value)
A one liner solution:
print(sum('0123456789'.index(c) * 10 ** exp for exp, c in enumerate(reversed('5768'))))
Convert to int using eval:
str = '0123456789'
def str_to_int(str):
return eval(str.lstrip("0"))
print(str_to_int(str))
print(type(str_to_int(str)))
Returns:
123456789
<class 'int'>

Double Slash Assignment division in Python [duplicate]

This question already has answers here:
What exactly does += do?
(17 answers)
Closed 3 years ago.
I am new to Python and found a function that checks to see if an array of arguments can be made equal by only multiplying the number by 2. However, there is some notation that I do not understand.
Function:
def isEqual(a,n): # a is an arrary, n is the length of array
for i in range(0,n):
while a[i]%2==0:
a[i]//=2 # this is the part I do not understand
print(a[i])
if a[i] != a[0]:
return print("False")
# Otherwise, all elements equal, return true
return print("True")
When I step through the function I see that it replaces the a[i] number by a[i]//2, but I do not understand why you would write // equals to number
I understand the // is "floor" division, but not why someone would write a[i]//=2. I would have thought to write it as a[i]=a[i]//2. I can only assume these are the same things, I just never saw it written this way.
Test code:
a = [50, 4, 2]
n = len(a)
isEqual(a, n)
You might have came across operations that also assign value. Think
a += 1 # same as: a = a + 1
This is exactly the same. It integer divides and assigns the value. Probably better understood with proper spacing:
a //= 2 # same as: a = a // 2

Categories