Converting Ints into binary / hex with ^ operator - python

I have two variables, Read and Out.
Read is a string e.g. "1101", Next there is Out which will be an int following the same binary format such as 100000 etc. I need to perform an operation so that If my two variables are
>>1000
>>1011
Output: 0011
I have tried to use Read ^ Out, I have tried to convert them to hex and do that but they always turn out as ints with other numbers ( 2-9 ). Output needs to be Int or a binary literal ( 0b0101 )
edit: This value is then sent off to another function like so Write( 0x20, 0x13, Out ). Whenever it gets sent Python automatically converts it to an int if its a binary, which causes problems later on.

^ works on ints.
You can convert strings to integers with a specified base:
int(x=0) -> integer
int(x, base=10) -> integer
For the opposite conversion there's bin().
In [1]: bin(int('1000', 2) ^ int('1011', 2))
Out[1]: '0b11'
The rest is a matter of string formatting. If you want to always have it in four digits and without the prefix, take a look at arshajii's answer.

I believe you're looking for a format operation in addition to ^:
>>> a = int('1000', 2)
>>> b = int('1011', 2)
>>> format(a ^ b, '04b')
'0011'
Notice that 11 in binary is equal to 0011:
>>> int('11', 2) == int('0011', 2)
True
It just comes down to how the number is represented as a string.

Use int() with a base of 2 to convert both variables:
>>> bin(int("1000", 2) ^ int(1011, 2))
>>> 0b11

Related

Formatting a float number without trailing zeros

When I do a simple division in Python 3, such as 123000/1000, I get 123.0, or 4/2 I get 2.0. How do I get rid of the trailing zero in Python 3's division?
EDIT:
I don't want just simple integer division. For ex, 1234/1000 should give 1.234.
To be clear, this question is about formatting the output, not internal representation.
Thanks all for your help! The answer came from #vaultah:
>>> f'{2.1:g}'
'2.1'
>>> f'{2.0:g}'
'2'
So just use regular division such as 4/2 and then format the string.
From the docs for 'g': https://docs.python.org/2/library/string.html#format-specification-mini-language
"insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it."
You could use something like this:
def remove_trailing_zeros(x):
return str(x).rstrip('0').rstrip('.')
remove_trailing_zeros(1.23) # '1.23'
remove_trailing_zeros(4.0) # '4
Normally, you would use standard string formatting options like '%2.1f' % number or any of the other many ways to format a string. However, you would then have to specify the amount of digits you want to display but in this case the number of trailing zeros to return is variable. The '%g' format specifier does not have this problem, but uses scientific notation and I don't know if that is what the OP wants.
The above solution converts the number to a "nicely printable string representation" (str(x)), and then removes trailing zeros (.rstrip('0')) and if necessary the remaining trailing period (.rstrip('.')) (to avoid "1." as a result) using standard string methods.
It's "correct" behaviour to have "floats" as a result, and .0 part simply indicates this fact. I think that what matter to you is "representation" of the result in the string. So you should not change actual result and only change the way it's "displayed". Use formatting mini language:
>>> for val in (123000/1000, 4/2, 1234/1000): print(f"{val:g}") # Use "General format" to represent floats
...
123
2
1.234
Mod is an O(1) operation which should add almost no overhead to your actual program. You could make it into a one liner also
x = a//b if not a % b else a/b
If you need to do this kind of thing a lot, make it into a function
def func(a, b):
return a//b if not a % b else a/b
func(10, 2) # out = 5
func(10, 3) # out = 3.333333333
func(1200, 100) # out = 12
func(1234, 1000) # out = 1.234
This works well for me. No scientific notation format for big numbers.
def no_trailing_zero(value: float) -> Union[float, int]:
return int(value) if value % 1 == 0 else float(str(value))
>>> no_trailing_zero(50)
50
>>> no_trailing_zero(50.11)
50.11
>>> no_trailing_zero(50.1100)
50.11
>>> no_trailing_zero(50.0)
50
>>> no_trailing_zero(500000000.010)
500000000.01
>>>
If you can guarantee that you get just a trailing zero, casting to int gets rid of it:
>>> 4/2
2.0
>>> int(4/2)
2
# // => used for integer output
# / => used for double output
x = 100/35 # => 2.857142857142857
y = 100//35 # => 2
z = 100.//35 # => 2.0 # floating-point result if divisor or dividend real

Python convert a string containing hex to actual hex

I have a hex string, but i need to convert it to actual hex.
For example, i have this hex string:
3f4800003f480000
One way I could achieve my goal is by using escape sequences:
print("\x3f\x48\x00\x00\x3f\x48\x00\x00")
However, I can't do it this way, because I want create together my hex from multiple variables.
My program's purpose is to:
take in a number for instance 100
multiply it by 100: 100 * 100 = 10000
convert it to hex 2710
add 0000
add 2710 again
add 0000 once more
Result I'm expecting is 2710000027100000. Now I need to pass this hexadecimal number as argument to a function (as hexadecimal).
In Python, there is no separate type as 'hex'. It represents the hexadecimal notation of the number as str. You may check the type yourself by calling it on hex() as:
# v convert integer to hex
>>> type(hex(123))
<type 'str'>
But in order to represent the value as a hexadecimal, Python prepends the 0x to the string which represents hexadecimal number. For example:
>>> hex(123)
'0x7b'
So, in your case in order to display your string as a hexadecimal equivalent, all you need is to prepend it with "0x" as:
>>> my_hex = "0x" + "3f4800003f480000"
This way if you probably want to later convert it into some other notation, let's say integer (which based on the nature of your problem statement, you'll definitely need), all you need to do is call int with base 16 as:
>>> int("0x3f4800003f480000", base=16)
4559894623774310400
In fact Python's interpreter is smart enough. If you won't even prepend "0x", it will take care of it. For example:
>>> int("3f4800003f480000", base=16)
4559894623774310400
"0x" is all about representing the string is hexadecimal string in case someone is looking/debugging your code (in future), they'll get the idea. That's why it is preferred.
So my suggestion is to stick with Python's Hex styling, and don't convert it with escape characters as "\x3f\x48\x00\x00\x3f\x48\x00\x00"
From the Python's hex document :
Convert an integer number to a lowercase hexadecimal string prefixed with “0x”. If x is not a Python int object, it has to define an index() method that returns an integer.
try binascii.unhexlify:
Return the binary data represented by the hexadecimal string hexstr.
example:
assert binascii.unhexlify('3f4800003f480000') == b"\x3f\x48\x00\x00\x3f\x48\x00\x00"
>>> hex(int('3f4800003f480000', 16))
'0x3f4800003f480000'

python adding binary number

There is an unexpected output when I am dealing with binary number in Python 3.
We can easily convert any integer to binary by built-in bin() function. For example:
>>>bin(4243125)
Here's the issue when I try to add 2 binary function:
>>>bin(x)+bin(y)
The output is concatenation of two binary number, not addition of binary number. The output of binary function has become a string.
Addition in a binary function works fine:
>>>bin(x+y)
And try to add two binary number without bin() is viable too:
>>>0b100+0b10111
What is the reasons/purposes of setting a bin() output to a string?
bin, like hex, converts a decimal to a string literal representing the number in that base.
If you want to add 2 numbers together simply do so:
x = 10
y = 2
x + y
If you want to take binary strings as input and add them together convert them back from string literals with int base 2, like this:
x = bin(10)
y = bin(2)
int(x, 2) + int(y, 2)
If you're looking to do bitwise operations look at the Python bitwise operators:
https://wiki.python.org/moin/BitwiseOperators

How to convert floating point number in python?

How to convert floating point number to base-16 numbers, 8 hexadecimal digits per 32-bit FLP number in python?
eg : input = 1.2717441261e+20 output wanted : 3403244E
If you want the byte values of the IEEE-754 representation, the struct module can do this:
>>> import struct
>>> f = 1.2717441261e+20
>>> struct.pack('f', f)
'\xc9\x9c\xdc`'
This is a string version of the bytes, which can then be converted into a string representation of the hex values:
>>> struct.pack('f', f).encode('hex')
'c99cdc60'
And, if you want it as a hex integer, parse it as such:
>>> s = struct.pack('f', f).encode('hex')
>>> int(s, 16)
3382500448
To display the integer as hex:
>>> hex(int(s, 16))
'0xc99cdc60'
Note that this does not match the hex value in your question -- if your value is the correct one you want, please update the question to say how it is derived.
There are several possible ways to do so, but none of them leads to the result you wanted.
You can code this float value into its IEEE binary representation. This leads indeed to a 32 bit number (if you do it with single precision). But it leads to different results, no matter which endianness I suppose:
import struct
struct.pack("<f", 1.2717441261e+20).encode("hex")
# -> 'c99cdc60'
struct.pack(">f", 1.2717441261e+20).encode("hex")
# -> '60dc9cc9'
struct.unpack("<f", "3403244E".decode("hex"))
# -> (687918336.0,)
struct.unpack(">f", "3403244E".decode("hex"))
# -> (1.2213533295835077e-07,)
As the other one didn't fit result-wise, I'll take the other answers and include them here:
float.hex(1.2717441261e+20)
# -> '0x1.b939919e12808p+66'
Has nothing to do with 3403244E as well, so maybe you want to clarify what exactly you mean.
There are surely other ways to do this conversation, but unless you specify which method you want, no one is likely to be able to help you.
There is something wrong with your expected output :
import struct
input = 1.2717441261e+20
buf = struct.pack(">f", input)
print ''.join("%x" % ord(c) for c in struct.unpack(">4c", buf) )
Output :
60dc9cc9
Try float.hex(input) if input is already a float.
Try float.hex(input). This should convert a number into a string representing the number in base 16, and works with floats, unlike hex(). The string will begin with 0x however, and will contain 13 digits after the decimal point, so I can't help you with the 8 digits part.
Source: http://docs.python.org/2/library/stdtypes.html#float.hex

Python 2.7 Reading Hex and Dec as Str and then adding them

Today I am reading in a file, and extracting information. I've figured out pretty much everything, but for some reason I am having a very, very annoying problem! I read in an entire line and use the .split() command to break the 'sentence' into 'words' right? And then I alias the 'words' as such:
startAddress = line[ 0 ]
length = line[ 2 ].strip( "(" ).strip( ")" )
...
endAddress = startAddress + length
Note: I strip the length because in the data file it is encased with () which, later, cause problems when I load it into a .csv file because () are used as negatives.
Anyways, if I were to have 0x00230008 be the start address and (4) be the length, my program makes 0x002300084 be the end address instead of 0x00230008C, but if I do hex(length) or hex(startAddress) or even hex(str(length) or hex(str(startAddress)) it throws an error saying hex numbers cannot be converted into hex. Likewise I cannot convert them into integers, either.
Really, all I need to do is add the starting address (which is in Hex, but reads in as a string) and the length (which is in int and reads in as int.) I have tried converting them around, but that didn't work. I also tried the line
endAddress = startAddress + length - 1
which tells me " unsupported operand type(s) for -: 'str' and 'int' " so, I've toyed with it as much as I can, but I'm just not figuring this out. I was thinking of removing the 0x in front of the hex value via strip, but then it reads in as an integer and is incorrect.
The last thing I tried was using line[ 0 ] and line[ 2 ] (with strips) directly to find endAddress, but it gives all the same errors. I tried to force type by stating that startAddress = 0xFFFFFFFF before I assign it equal to line[ 0 ], but that didn't work. So how the heck do I convert a string to a hexidecimal number if it complains that it is hexidecimal when it is not? Or maybe my method of adding them is wrong? Can I use some other adding method?
The biggest confusion for me is that if I try to convert startAddress to a string, and then back into a hexidecimal number, it still complains.
int takes an optional parameter specifying the base of integer you want to convert it into. So you could simple call something like:
proper_int = int(number, 16)
To get a proper representation.
For example:
int("10", 16) = 16
int("F0", 16) = 240
int("0x10", 16) = 16
If you want to add zero padding I would recommend zfill:
"10".zfill(4) = "0010"
You have to parse the string as a base-16 int
>>> int("0x00230008", 16)
2293768
Add the ints
>>> int("0x00230008", 16) + 4
2293772
And convert it back to a hex string:
>>> hex(int("0x00230008", 16) + 4)
'0x23000c'
You'll have to use some string formatting instead of hex to pad it with zeroes, if you need it:
>>> '0x%08x' % (int("0x00230008", 16) + 4)
'0x0023000c'
int() defaults to base-10, so specify the base when calling int on a base-16 string:
>>> int('0x00230008', 16)
2293768
Use int or eval function:
>>> int('0x002300084', 16)
36700292
>>> eval('0x002300084')
36700292
>>> hex(36700292)
'0x2300084'
hex, oct and bin functions all take integers and return string
while int takes string (or unicode), and an optional base argument (default to 10) and returns and integer

Categories