OR element wise operation over two binary lists - python

I have the following code of two binary lists and I want to obtain a resulting list in which the element i will be the OR operation applied to the i elements of the two lists:
from operator import ior
l_0 = [01100]
l_1 = [11000]
print map(ior, l_0, l_1)
And I was expecting a result of [11100], but the result is:
[11000]
I have checked ior operator and the documentation says that it performs the operation:
a = ior(a, b) is equivalent to a |= b
So I tried the following to check as well:
print ior(0,0)
print ior(1,0)
print ior(0,1)
print ior(1,1)
Getting as results:
0
1
1
1
Which makes sense, but doesn't coincide with the result obtained in the 3rd position of the lists. I don't understand why the result of the map operation of above is not [11100]. I am missing something here and I hope that you can throw some light on it.

[11000] (for example) is not a list of five binary digits, it's a list of one decimal number, 11000.
Similarly, 01100 is a single octal number equal to 576 decimal, so:
11000d = 0010101011111000b
01100o = 576d = 0000001001000000b
-----------------
perform or: 0010101011111000b = 11000d
That's why you're getting 11000 as the answer, exactly the same as if you'd done:
[l_0[i] | l_1[i] for i in range(len(l_0))]
If you want to process a list of five binary digits, that would be something like:
>>> l_0 = [0,1,1,0,0]
>>> l_1 = [1,1,0,0,0]
>>> [l_0[i] | l_1[i] for i in range(len(l_0))]
[1, 1, 1, 0, 0]

01100 is octal representation (576 in decimal). 11000 is decimal representation. They are not binary representations.
To represent binary, prefix them with 0b:
[`01100`, `11000`]
And to get binary representation from the number use bin:
bin(num)
or
'{:b}'.format(num)

Related

How to print a float in 5 significant digit scientific notation in Python/numpy? [duplicate]

I have a number like 2.32432432423e25 in python that is the result of a computation.
I want to round this to 3 decimal points to get the output:
2.324e25
I have tried to use:
x = 2.32432432423e25
number_rounded = round(x, 3)
But when I print number_rounded it outputs a number with the same format as x.
How do I limit the display of x to just 4 significant digits?
You'll need to use string formatting for this:
'{:0.3e}'.format(2.32432432423e25)
The reason is that round is for specifying the number of the digits after the ones place, which is not really relevant when your numbers are O(25).
If you want to use Python's f-string syntax introduced in Python 3.6, specify the format after the variable, separated by :, e.g.:
>>> res = 2.32432432423e25
>>> f'The result is {res:.3e}'
'The result is 2.324e+25'
I was looking for an answer to this and mostly found string answers. While that is typically the best way to handle this question (because floats are always rounded to their defined precision regardless), there are situations where you'd like to round a float to a given decimal precision (plus whatever float imprecision added on) and I couldn't find a good answer. Here's what I came up with, I believe it handles all the possible cases: input of zero, input < 1, input > 1 for both positive and negative numbers:
def precision_round(number, digits=3):
power = "{:e}".format(number).split('e')[1]
return round(number, -(int(power) - digits))
Building on top of #Josh Duran nice function/idea, here is the same func that can handle up-to 2-D arrays. Maybe someone can modify this for the ndarrays.
def precision_round(numbers, digits = 3):
'''
Parameters:
-----------
numbers : scalar, 1D , or 2D array(-like)
digits: number of digits after decimal point
Returns:
--------
out : same shape as numbers
'''
import numpy as np
numbers = np.asarray(np.atleast_2d(numbers))
out_array = np.zeros(numbers.shape) # the returning array
for dim0 in range(numbers.shape[0]):
powers = [int(F"{number:e}".split('e')[1]) for number in numbers[dim0, :]]
out_array[dim0, :] = [round(number, -(int(power) - digits))
for number, power in zip(numbers[dim0, :], powers)]
# returning the original shape of the `numbers`
if out_array.shape[0] == 1 and out_array.shape[1] == 1:
out_array = out_array[0, 0]
elif out_array.shape[0] == 1:
out_array = out_array[0, :]
return out_array

Summation of large numbers in python yields the maximal parameter

In my program I use numpy to get number's exponents, then I use the sum function to summarize them.
I've noticed that summarizing those large numbers, with or without numpy, results in the largest parameter being returned, unchanged.
exp_joint_probabilities=[ 1.57171938e+81, 1.60451506e+56, 1.00000000e+00]
exp_joint_probabilities.sum()
=> 1.571719381352921e+81
The same with just python:
(1.57171938e+81+1.60451506e+56+1.00000000e+00)==1.57171938e+81
=>True
Is this a problem with approximation? Should I use a larger datatype to represent the numbers?
How can I get a more accurate result for these kind of calculations?
You could use the decimal standard library:
from decimal import Decimal
a = Decimal(1.57171938e+81)
b = Decimal(1.60451506e+56)
d = a + b
print(d)
print(d > a and d > b)
Output:
1.571719379999999945626903708E+81
True
You could convert it back to a float afterwards, but this will cause the same problem as before.
f = float(d)
print(f)
print(f > a and f > b)
Output:
1.57171938e+81
False
Note that if you store Decimals in your numpy arrays, you will lose fast vectorized operations, as numpy does not recognize Decimal objects. Though it does work:
import numpy as np
a = np.array([1.57171938e+81, 1.60451506e+56, 1.00000000e+00])
d = np.vectorize(Decimal)(a) # convert values to Decimal
print(d.sum())
print(d.sum() > d[0]
Output:
1.571719379999999945626903708E+81
True
1.57171938e+81 is a number with 81 digits, of which you only enter the first 9. 1.60451506e+56 is a much much much smaller number, with only 56 digits.
What kind of answer are you expecting? The first utterly dwarfs the second. If you want something of a similar precision to your original numbers (and that's what you get using floats), then the answer is simply correct.
You could use ints:
>>> a = int(1.57171938e+81)
>>> b = int(1.60451506e+56)
>>> a
571719379999999945626903548020224083024251666384876684446269499489505292916359168L
>>> b
160451506000000001855754747064077065047170486040598151168L
>>> a+b
1571719379999999945626903708471730083024253522139623748523334546659991333514510336L
But how useful that is is up to you.
It does seem to be a problem with approximation:
>>> 1.57171938e+81 + 1.60451506e+65 > 1.57171938e+81
<<< True
>>> 1.57171938e+81 + 1.60451506e+64 > 1.57171938e+81
<<< False
You can get arount this by casting to int:
>>> int(1.57171938e+81) + int(1.60451506e+64) > int(1.57171938e+81)
<<< True

append 2 hex values in python

I am trying to append some hex values in python and I always seem to get 0x between the number. From what I searched, either this is not possible without converting it into a lit of values ?? I am not sure.
a = 0x7b
b = 0x80000
hex(a) + hex(b) = 0x7b0x80000
I dont want the 0x in the middle - I need, 0x7b80000. is there any other way to do this? If I convert to integer I get the sum of the two and converting it to hex is a different value than 0x7b80000
I don't think you want to "append" them. Doing integer arithmetic by using strings is a bad idea. I think you want to bit-shift a into the right place and OR them together:
>>> a = 0x7B
>>> b = 0x80000
>>>
>>> hex( (a<<20) | b )
'0x7b80000'
Perhaps if you were more specific about what these numbers are and what exactly you're trying to accomplish I could provide a more general answer.
You can use f-string formatting with Python 3:
>>> a = 0x7b
>>> b = 0x80000
>>> f'0x{a:x}{b:x}'
'0x7b80000'
This is a more generic way to append hex / int / bin values.
Only works for positive values of b.
a = 0x7b
b = 0x80000
def append_hex(a, b):
sizeof_b = 0
# get size of b in bits
while((b >> sizeof_b) > 0):
sizeof_b += 1
# align answer to nearest 4 bits (hex digit)
sizeof_b += sizeof_b % 4
return (a << sizeof_b) | b
print(hex(append_hex(a, b)))
Basically you have to find the highest set bit that b has.
Align that number to the highest multiple of 4 since that's what hex chars are.
Append the a to the front of the highest multiple of 4 that was found before.
It's been 7 years but the accepted answer is wrong and this post still appears in the first place in google searches; so here is a correct answer:
import math
def append_hex(a, b):
sizeof_b = 0
# get size of b in bits
while((b >> sizeof_b) > 0):
sizeof_b += 1
# every position in hex in represented by 4 bits
sizeof_b_hex = math.ceil(sizeof_b/4) * 4
return (a << sizeof_b_hex) | b
The accepted answer doesn't make sense (you can check it with values a=10, b=1a). In this solution, we search for the nearest divider of 4 - since every hex value is represented by 4 bits - and then move the first value this time of bits.

Binary to Decimal (mathematics way)

If there is an binary number:10011100
It is 156 in decimal.
I want to use mathematics way to make binary to decimal.
For example:
binary: 10011100
the first number is 1: 2**7
the forth number is 1: 2**4
the fifth number is 1: 2**3
the sixth number is 1: 2**2
then 2**7+2**4+2**3+2**2 = 156
I think, I need to use string.find() method.
>>> my_str = '10011100'
>>> my_str = my_str[::-1]
>>> print(my_str)
00111001
>>> my_str.find('1')
2
>>>
I just can find the first '1'.
How to find all the index of '1'?
Why do you want to retrieve the indexes? You can simply iterate over the bits like this:
num = sum(2**i for i, bit in enumerate(my_str) if bit == '1')
Anyway, you can get the indexes like this if you prefer two separate steps:
indexes = [i for i, bit in enumerate(my_str) if bit == '1']
num = sum(2**i for i in indexes)
You may also check the built-in int() function that takes a base argument:
int(x[, base]) -> integer
In [1]: my_str = '10011100'
In [2]: int(my_str,2)
Out[2]: 156
Binary Number:
If you are considering why binary number has a base 2 always well the answer is a binary number is expressed in the base-2 because it uses only two symbols: typically "0" (zero) and "1" (one). eg 10011100 (only "zero" and "one" used)
If there is an binary number:10011100 It is 156 in decimal.
The Binary number here is 10011100 it always has a base 2 even if it is not written 10011100 is same as 10011100 base 2
Convert Binary to Decimal
We start from the most right number and move toward left
Multi the binary number with 2 that is the base and the power(^) keeps increasing by 1
(0*2^0)+(0*2^1)+(1*2^2)+(1*2^3)+(1*2^4)+(0*2^5)+(0*2^6)+(1*2^7)
=156
If you want to under stand more clearly here is a link
[https://www.mathwarehouse.com/non-decimal-bases/convert-binary-to-decimal.php?ref=driverlayer.com][1]

Binary numbers in Python

How can I add, subtract, and compare binary numbers in Python without converting to decimal?
You can convert between a string representation of the binary using bin() and int()
>>> bin(88)
'0b1011000'
>>> int('0b1011000', 2)
88
>>>
>>> a=int('01100000', 2)
>>> b=int('00100110', 2)
>>> bin(a & b)
'0b100000'
>>> bin(a | b)
'0b1100110'
>>> bin(a ^ b)
'0b1000110'
I think you're confused about what binary is. Binary and decimal are just different representations of a number - e.g. 101 base 2 and 5 base 10 are the same number. The operations add, subtract, and compare operate on numbers - 101 base 2 == 5 base 10 and addition is the same logical operation no matter what base you're working in. The fact that your python interpreter may store things as binary internally doesn't affect how you work with it - if you have an integer type, just use +, -, etc.
If you have strings of binary digits, you'll have to either write your own implementation or convert them using the int(binaryString, 2) function.
If you're talking about bitwise operators, then you're after:
~ Not
^ XOR
| Or
& And
Otherwise, binary numbers work exactly the same as decimal numbers, because numbers are numbers, no matter how you look at them. The only difference between decimal and binary is how we represent that data when we are looking at it.
Binary, decimal, hexadecimal... the base only matters when reading or outputting numbers, adding binary numbers is just the same as adding decimal number : it is just a matter of representation.
Below is a re-write of a previously posted function:
def addBinary(a, b): # Example: a = '11' + b =' 100' returns as '111'.
for ch in a: assert ch in {'0','1'}, 'bad digit: ' + ch
for ch in b: assert ch in {'0','1'}, 'bad digit: ' + ch
sumx = int(a, 2) + int(b, 2)
return bin(sumx)[2:]
'''
I expect the intent behind this assignment was to work in binary string format.
This is absolutely doable.
'''
def compare(bin1, bin2):
return bin1.lstrip('0') == bin2.lstrip('0')
def add(bin1, bin2):
result = ''
blen = max((len(bin1), len(bin2))) + 1
bin1, bin2 = bin1.zfill(blen), bin2.zfill(blen)
carry_s = '0'
for b1, b2 in list(zip(bin1, bin2))[::-1]:
count = (carry_s, b1, b2).count('1')
carry_s = '1' if count >= 2 else '0'
result += '1' if count % 2 else '0'
return result[::-1]
if __name__ == '__main__':
print(add('101', '100'))
I leave the subtraction func as an exercise for the reader.
For example, 00000011 - 00000001 = 00000010
You can remove the zeroes and then add them again after you do your calculation! This works very easy.
If your binary is stored as a string then you can convert to int which will automatically strip the zeroes from the start. After you have your answer you can turn it back into a string and add the zeroes to the start.
Not sure if helpful, but I leave my solution here:
class Solution:
# #param A : string
# #param B : string
# #return a strings
def addBinary(self, A, B):
num1 = bin(int(A, 2))
num2 = bin(int(B, 2))
bin_str = bin(int(num1, 2)+int(num2, 2))
b_index = bin_str.index('b')
return bin_str[b_index+1:]
s = Solution()
print(s.addBinary("11", "100"))
x = x + 1
print(x)
a = x + 5
print(a)
I think you're confused about what binary is. Binary and decimal are just different representations of a number - e.g. 101 base 2 and 5 base 10 are the same number. The operations add, subtract, and compare operate on numbers - 101 base 2 == 5 base 10 and addition is the same logical operation no matter what base you're working in.

Categories

Resources