I am generating the input for an FPGA program to use the trapezoidal integration method. Basically, the functions of interest here are the invert() and twos_comp() functions; the rest is just testing (creating a square wave signal, and then iterating through and converting it into two's complement).
signals = []
bit_signals = []
def invert(bit_val):
new_val = []
for i in bit_val:
new_val.append(str(int(not(int(i)))))
return ''.join(new_val)
def twos_comp(val):
if val < 0:
bin_val = format(val, '08b')[1:]
return format(int(invert(bin_val),2) + int('1', 2), '08b')
else:
bin_val = format(val, '08b')[1:]
return bin_val
x = 0
signal = 1
while x <= 25:
if x % 2 == 0:
signal*=-1
signals.append(signal)
x+=1
print(signals)
for i in signals:
bit_signals.append(twos_comp(i))
print(bit_signals)
The problem here is that this outputs the two's complement for 1 as 01111111, not 1111111. The output of invert() seems to be correct, the output for twos_comp() for positive numbers seems to be correct, and the generation of the signal also appears to be correct, so I think it must be something with the line
return format(int(invert(bin_val),2) + int('1', 2), '08b')
but looking around on SO and google this is how other people have handled adding in binary.
Please note that all inputs to twos_comp() will be 8 bits. Any help would be appreciated as to why this is not working. There are no outright errors, just an incorrect output.
You can run the code here.
Step through the values when val is -1:
>>> format(-1, '08b')
'-0000001'
You may have already spotted the error—08b means 8 characters wide, not 8 digits. For a negative number, the - takes up 1 of the characters, so you only get 8 digits. But in case it isn't obvious why that's a problem, let's keep going:
>>> format(val, '08b')[1:]
'0000001'
>>> invert('0000001')
'1111110'
>>> int(invert('0000001'), 2)
126
>>> int('1', 2) # BTW, why do you need this instead of just 1, exactly?
1
>>> 126 + 1
127
>>> format(127, '08b')
01111111
If you want a hacky solution (and I suspect you do, since you're already going back and forth between strings and numbers all over the place), just do this:
bin_val = format(val, '09b')[-8:]
That will work for both positive and negative numbers.
Related
I tried to solve this Kata problem
Write a function that takes an integer as input, and returns the number of bits that are equal to one in the binary representation of that number. You can guarantee that input is non-negative.
Example: The binary representation of 1234 is 10011010010, so the function should return 5 in this case.
But the problem is my code gives the correct answers right for the first time around but when
it is run for 2nd time onward it gives wrong answers only. I think it has to do sth with how my code is recursive. Please help me figure it out.
for example when i run count_bits(24) it gives the output 2 which is correct but when i run the same function again it would give 4 and then 6 and so on . I dont know what's wrong with this
My code.
dec_num = []
def count_bits(n):
def DecimalToBinary(n):
if n >= 1:
DecimalToBinary(n // 2)
dec_num.append( n % 2)
return dec_num
dec = DecimalToBinary(n)
return dec.count(1)
There is no need to create a list of digits if all you need is their sum. When possible, avoid creating mutable state in a recursive solution:
def count_bits(n):
if n > 0:
return n % 2 + count_bits(n // 2)
else:
return 0
That's a pretty natural translation of the obvious algorithm:
The sum of the bits in a number is the last bit plus the sum of the bits in the rest of the number.
Sometimes it's convenient to accumulate a result, which is best done by adding an accumulator argument. In some languages, that can limit stack usage, although not in Python which doesn't condense tail calls. All the same, some might find this more readable:
def count_bits(n, accum = 0):
if n > 0:
return count_bits(n // 2, accum + n % 2)
else:
return accum
In Python, a generator is a more natural control structure:
def each_bit(n):
while n > 0:
yield n % 2
n //= 2
def count_bits(n):
return sum(each_bit(n))
Of course, there are lots more ways to solve this problem.
That is because dec_num is outside the method, so it's reused at every call, put it inside
def count_bits(n):
dec_num = []
def DecimalToBinary(n):
if n >= 1:
DecimalToBinary(n // 2)
dec_num.append(n % 2)
return dec_num
dec = DecimalToBinary(n)
return dec.count(1)
I just started a course in Python and trying this code:
import math
c = int(input('Enter number: '))
a = 1
counter = 0
while counter != 2:
a = a + 1
b = round((c-(a**3))**(1/3.0))
if a < b and a**3 + b**3 == c:
counter = counter + 1
print(a,b)
My problem is that python cant round the 'b' since it is viewed as a complex number...
The program is supposed to find two sets of a & b that satisfie a^3+b^3=c, any feed back on my code is appreciated.
Basically, raising a negative number to a fractional power always yields a complex number. For example, sqrt(-1) (which is (-1)**(1/2)), is clearly complex.
So, if you try to raise -8 to the 1/3th power, you'll get a complex number. For example:
a = (-8)**(1/3)
print(a)
print(a**3)
Will print
(1.0000000000000002+1.7320508075688772j)
(-8+3.1086244689504383e-15j)
That gives back -8 when raised to the 3rd power, give or take some rounding.
This rounding is the real issue here. You could well say that -8 to the power 1/3 is -2, as -2 to the 3rd power is -8. However - and this is the crux - that only works if the power is actually 1/3. In a floating point number it will actually be 0.33333 (with some more threes), which is not exactly the same. Hence the exponentiation is done with complex numbers.
You'll either have to work with complex numbers, or rewrite your maths to not use fractional powers of negative numbers.
You need to guard your computation against a^3 being larger than c; that's what returns a complex number. Make sure that you move the increment of a, so that the while uses that same value. Perhaps
while counter != 2 and c >= a**3:
b = round((c-(a**3))**(1/3.0))
if a < b and a**3 + b**3 == c:
counter = counter + 1
print(a,b)
a = a + 1
Output with c = 1729, the Ramanujan-Hardy number:
1 12
9 10
Also, why are you waiting for two solutions? "counter" puzzles me ... you could use a Boolean flag if you need only one solution.
Ive been give a task, it is as follows:
write a function called decToBin that takes in an integer and converts it to an 8-bit binary number represented as a string
As I am new to this im very lost! Having no introduction to my task as thrown me off a little and I really need some help!
I have tried the following code:
#function
def decTobin(integer)
return bin
#main program
decToBin(3)
decToBin(4)
decToBin(5)
However I had no sucess, could someone point me in the right direction, it would be much appreciated, thank you!
Please try to keep your questions tidy. Also, judging from your other questions, you should look at some basic python tutorials. Happy coding!
Try to learn about base conversions. Here is a great place to find a step by step walkthrough for doing it manually.
You will need to use the modulo (%) operator. The modulo operator is a binary operator, meaning it has two inputs. You use it like so:
a % b
It returns the remainder when a is divided by b:
10 % 7 = 3
The following code will do what you need:
def decToBin(x):
if x == 0:
return "00000000"
bits = []
while x:
bits.append(str(x % 2))
x >>= 1
return "".join(bits).zfill(8)
I will explain line by line.
def decToBin(x):
This declares the function.
if x == 0:
return "00000000"
This returns a string of eight zeros if the input is zero. We need this because the while loop only operates when x is not equal to zero.
bits = []
This initializes the array of bits. During the while loop, we will add to this with the append function.
while x:
This begins a while loop, which runs until x is false (or zero).
bits.append(str(x % 2))
This adds to the bits array the remainder when x is divided by 2. str() converts it to a string.
x >>= 1
>>= 1 Shifts the bits in x to the right one time like so:
Before: 1 1 0 1 0 1
After: 0 1 1 0 1 0
It is the same as dividing by 2, without keeping the remainder.
return "".join(bits).zfill(8)
Breakdown:
"abc".join(l)
Joins all the strings in list l, separating it with abc.
"2345".zfill(i)
adds zeros to the beginning of a string until there are i numbers. So
return "".join(bits).zfill(8)
returns the array of bits as one string, and pads the beginning until there are eight characters.
How do you count the number of ones in a given integer's binary representation.
Say you are given a number 20, which is 10100 in binary, so number of ones is 2.
What you're looking for is called the Hamming weight, and there are a lot of algorithms to do it. Here's another straightforward one:
def ones(n):
w = 0
while (n):
w += 1
n &= n - 1
return w
Use the awesome collections module.
>>> from collections import Counter
>>> binary = bin(20)[2:]
>>> Counter(binary)
Counter({'0': 3, '1': 2})
Or you can use the built-in function count():
>>> binary = bin(20)[2:]
>>> binary.count('1')
2
Or even:
>>> sum(1 for i in bin(20)[2:] if i == '1')
2
But that last solution is slower than using count()
>>> num = 20
>>> bin(num)[2:].count('1')
2
The usual way to make this blinding fast is to use lookup tables:
table = [bin(i)[2:].count('1') for i in range(256)]
def pop_count(n):
cnt = 0
while n > 0:
cnt += table[n & 255]
n >>= 8
return cnt
In Python, any solution using bin and list.count will be faster, but this is nice if you want to write it in assembler.
The int type has a new method int.bit_count() since python 3.10a, returning the number of ones in the binary expansion of a given integer, also known as the population count as follows:
n = 20
bin(n)
'0b10100'
n.bit_count() returns 2 as it has 2 ones in the binary representation.
The str.count method and bin function make short work of this little challenge:
>>> def ones(x):
"Count the number of ones in an integer's binary representation"
return bin(x).count('1')
>>> ones(20)
2
You can do this using bit shifting >> and bitwise and & to inspect the least significant bit, like this:
def count_ones(x):
result = 0
while x > 0:
result += x & 1
x = x >> 1
return result
This works by shifting the bits right until the value becomes zero, counting the number of times the least significant bit is 1 along the way.
I am a new coder and I found this one logic simple. Might be easier for newbies to understand.
def onesInDecimal(n):
count = 0
while(n!=0):
if (n%2!=0):
count = count+1
n = n-1
n = n/2
else:
n = n/2
return count
For a special case when you need to check quickly whether the binary form of the integer x has only a single 1 (and thus is a power of 2), you can use this check:
if x == -(x | (-x)):
...
The expression -(x | (-x)) is the number that you get if you replace all 1s except the last one (the least significant bit) in the binary representation of x with 0.
Example:
12 = 1100 in binary
-12 = ...110100 in binary (with an infinite number of leading 1s)
12 | (-12) = ...111100 in binary (with an infinite number of leading 1s)
-(12 | (-12)) = 100 in binary
If the input number is 'number'
number =20
len(bin(number)[2:].replace('0',''))
Another solution is
from collections import Counter
Counter(list(bin(number))[2:])['1']
def isinteger(x):
while x > 0.0:
x = x - 1.0
if x < 0.0:
return 0.0
elif x == 0:
return 1.0
d = input('')
print isinteger(d)
The code is somewhat self explanatory. I'm using it for a fractran interpreter. Here is my problem: I input a fraction, such as 22/7, and I get a 1 as my output. Does it have something to do with python's IO?
The input function evaluates your 22/7 exactly the same way as if it had been entered into the python interpreter. Since both 22 and 7 are integers you get an integer division with a result of 3. If you want float division, enter either 22.0/7 or 22/7.0 both of which result in 3.146....
If you're using python 2, inputting "22/7" directly leads to integer division, i.e. it rounds your input down to 3, thus the algorithm returns 1. Try inputting 22.0/7 instead.
Also, you might want to consider faster alternatives to this algorithm if you're using it for anything real. Possibilities:
def isinteger(x):
return int(x) == x
def isinteger(x):
return isinstance(x, int)
22.0/7 vs 22/7 aside, there is another problem with this approach: it does not work in the majority of programming languages, because of the way floating point numbers are represented. For example, using your original function:
In [37]: isinteger(190.000000000000000001)
Out[37]: 1.0
Using Sean's int(x) == x suggestion:
In [39]: x = 190.000000000000000001
In [40]: int(x) == x
Out[40]: True
I realize it doesn't directly address the question, but I hope it will prevent a future one :)
If you want to check for integer for example for finding big perfect squares, you must consider inaccuracy of binary representations (abs is not needed for positive numbers, but is needed for negative numbers):
x = -190.00000000001
print int(x) == x
epsilon = 1E-10
def isinteger(n):
" near enoungh to pass as integer considering round of errors "
return abs(n-int(n)) < epsilon
print isinteger(x)
Implied eval of Python2 is considered too powerfull to be safe. If you want to input numbers instead of let user to give any formula (and in every case you need to add try...except handling for the users input):
number = raw_input('Give number: ')
number = int(number) if all(c.isdigit() for c in number) else float(number)
print number
your inputs are both integers so it results in giving 3 as input thereby it produces 1 as output.