I have this hexstr 0xfffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877, in decimal terms it should give -580140491462537. However doing the below leads to bad answers. Can someone help?
In: test = '0xfffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877'
In: int(test,16)
Out: 11579208923731619542357098500868790785326998466564056403945758342777263817739
First convert the string to bytes. You'll have to remove the leading "0x".
Then use int.from_bytes and specify that it's signed and big-endian.
In: int.from_bytes(bytes.fromhex(test[2:]), byteorder="big", signed=True)
Out: -580140491462537
I've adapted this answer
# hex string to signed integer
def htosi(val):
uintval = int(val, 16)
bits = 4 * len(val)
indicative_binary = 2 ** (bits)
indicative_binary_1 = 2 ** (bits-1)
if uintval >= indicative_binary_1:
uintval = int(0 - (indicative_binary - uintval))
return uintval
This does require a pure hex string:
test1 = 'fffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877'
print(htosi(test1))
-580140491462537
I have int in python that I want to reverse
x = int(1234567899)
I want to result will be 3674379849
explain : = 1234567899 = 0x499602DB and 3674379849 = 0xDB029649
How to do that in python ?
>>> import struct
>>> struct.unpack('>I', struct.pack('<I', 1234567899))[0]
3674379849
>>>
This converts the integer to a 4-byte array (I), then decodes it in reverse order (> vs <).
Documentation: struct
If you just want the result, use sabiks approach - if you want the intermediate steps for bragging rights, you would need to
create the hex of the number (#1) and maybe add a leading 0 for correctness
reverse it 2-byte-wise (#2)
create an integer again (#3)
f.e. like so
n = 1234567899
# 1
h = hex(n)
if len(h) % 2: # fix for uneven lengthy inputs (f.e. n = int("234",16))
h = '0x0'+h[2:]
# 2 (skips 0x and prepends 0x for looks only)
bh = '0x'+''.join([h[i: i+2] for i in range(2, len(h), 2)][::-1])
# 3
b = int(bh, 16)
print(n, h, bh, b)
to get
1234567899 0x499602db 0xdb029649 3674379849
I need to create a calculator that can add numbers in base 12 and with different limits at the differents diggits.
Base 12 sequence: [0,1,2,3,4,5,6,7,8,9,"A","B"]
The limits must be:
First digit: limit "B"
Second digit: limit 4
That means you would count like this:[1,2,3,4,5,6,7,8,9,A,B,10,11,...48,49,4A,4B]
but I don´t know how could I make it so that I can sum 2 numbers
I have the following code in python:
list1=[0,1,2,3,4,5,6,7,8,9,"A","B"]
list2=[0,1,2,3,4]
list3=[0,1,2,3,4,5,6,7,8,9,"A","B"]
list4=[0,1,2,3,4]
def calculadora (entrada1, operacion, entrada2):
#parte de valor 1:
digito1_1=str(list2[int(entrada1//12)])
digito1_2=str(list1[int(entrada1%12)])
valor1=float(digito1_1+digito1_2)
#parte de valor 2
digito2_1=str(list2[int(entrada2//12)])
digito2_2=str(list1[int(entrada2%12)])
valor2=float(digito2_1+digito2_2)
if operacion==str("suma") or "+":
return float(valor1+valor2)
entrada1 = float(input("inserte primer valor"))
operacion=str(input("inserte operación"))
entrada2 = float(input("inserte segundo valor"))
print (calculadora(entrada1,operacion,entrada2))
It works for numbers but wenn I want to sum numbers like 3B, it gives me a ValueError as it is coded as string.
Could someone help me or say me how could I do it to sum such numbers please?
The easiest way to convert a base-12 encoded string to int is via int(string, 12). The reverse is not quite as easy, because Python doesn't seem to have a built-in way to do that. You can use format specifiers for binary, octal, and hex, but not arbitrary bases.
You can get a reversed list of digits using divmod(), which does division with remainder.
def to_digits(x, base):
while x > 0:
x, rem = divmod(x, base)
yield rem
But to round-trip, we want a string. Convert the int to a character (using a string as a lookup table), and join them into a string, then use a negatively-stepped slice to reverse it.
def to_base_12(num):
return ''.join('0123456789AB'[d] for d in to_digits(num, 12))[::-1]
With a longer lookup table, you could generalize this into higher bases.
Strings are already sequences, but if you want to convert that back to a list, you can just call list() on it. The inverse is that ''.join() method you just saw.
Now that you can convert your base-12 representation to Python int objects and back, you can simply add them with +.
Here is slight variation on the excellent answer from gilch that handles negative numbers and zero.
def convert_to_string(num, base):
'''
Convert integer (num) to base less than base 37.
'''
alpha = string.digits + string.ascii_lowercase
assert isinstance(num, int)
assert isinstance(base, int)
assert 1 < base <= len(alpha)
if num == 0:
return '0'
def to_digits(num, base, alpha):
'''
Generator to convert digits in reverse order.
'''
while num > 0:
num, rem = divmod(num, base)
yield alpha[rem]
sign = ''
if num < 0:
num, sign = -num, '-'
return sign + ''.join(d for d in reversed(tuple(to_digits(num, base, alpha))))
def convert_from_string(num, base):
'''
Convert string in base X to integer.
'''
return int(str(num), base)
def test():
'''
Test conversions.
'''
assert convert_to_string(0, 2) == '0'
assert convert_to_string(4, 2) == '100'
assert convert_to_string(23, 12) == '1b'
assert convert_to_string(-6, 2) == '-110'
assert convert_from_string('1b', 12) == 23
assert convert_from_string('-110', 2) == -6
You can add them directly if you convert the A and B to 11 and 12. Then as each number is now a list of digits one can add them the same way that an ALU does. See the section on addition of integers in any text on computer arithmetic.
def add(A, B):
result = []
carry = 0
for a, b in reversed(zip(A,B)):
carry, digit = divmod(a + b + carry, 12)
result.append(digit)
if carry:
result.append(carry)
result.reverse()
return result
>>> add([4,3],[6,11])
[11, 2]
>>> add([5,3],[6,11])
[1, 0, 2]
The lists are MSD first. The double reversing is not needed if the lists were in LSD first.
This is for a school project. I need to create a function using recursion to convert an integer to binary string. It must be a str returned, not an int. The base case is n==0, and then 0 would need to be returned. There must be a base case like this, but this is where I think I am getting the extra 0 from (I could be wrong). I am using Python 3.6 with the IDLE and the shell to execute it.
The function works just fine, expect for this additional zero that I need gone.
Here is my function, dtobr:
def dtobr(n):
"""
(int) -> (str)
This function has the parameter n, which is a non-negative integer,
and it will return the string of 0/1's
which is the binary representation of n. No side effects.
Returns bianry string as mentioned. This is like the function
dtob (decimal to bianary) but this is using recursion.
Examples:
>>> dtob(27)
'11011'
>>> dtob(0)
'0'
>>> dtob(1)
'1'
>>> dtob(2)
'10'
"""
if n == 0:
return str(0)
return dtobr(n // 2) + str(n % 2)
This came from the function I already wrote which converted it just fine, but without recursion. For reference, I will include this code as well, but this is not what I need for this project, and there are no errors with this:
def dtob(n):
"""
(int) -> (str)
This function has the parameter n, which is a non-negative integer,
and it will return the string of 0/1's
which is the binary representation of n. No side effects.
Returns bianry string as mentioned.
Examples:
>>> dtob(27)
'11011'
>>> dtob(0)
'0'
>>> dtob(1)
'1'
>>> dtob(2)
'10'
"""
string = ""
if n == 0:
return str(0)
while n > 0:
remainder = n % 2
string = str(remainder) + string
n = n // 2
Hopefully someone can help me get ride of that additional left hand zero. Thanks!
You need to change the condition to recursively handle both the n // 2 and n % 2:
if n <= 1:
return str(n) # per #pault's suggestion, only needed str(n) instead of str(n % 2)
else:
return dtobr(n // 2) + dtobr(n % 2)
Test case:
for i in [0, 1, 2, 27]:
print(dtobr(i))
# 0
# 1
# 10
# 11011
FYI you can easily convert to binary format like so:
'{0:b}'.format(x) # where x is your number
Since there is already an answer that points and resolves the issue with recursive way, lets see some interesting ways to achieve same goal.
Lets define a generator that will give us iterative way of getting binary numbers.
def to_binary(n):
if n == 0: yield "0"
while n > 0:
yield str(n % 2)
n = n / 2
Then you can use this iterable to get decimal to binary conversion in multiple ways.
Example 1.
reduce function is used to concatenate chars received from to_binary iterable (generator).
from functools import reduce
def to_binary(n):
if n == 0: yield "0"
while n > 0:
yield str(n % 2)
n = n / 2
print reduce(lambda x, y: x+y, to_binary(0)) # 0
print reduce(lambda x, y: x+y, to_binary(15)) # 1111
print reduce(lambda x, y: x+y, to_binary(15)) # 11011
Example 2.
join takes iterable, unrolls it and joins them by ''
def to_binary(n):
if n == 0: yield "0"
while n > 0:
yield str(n % 2)
n = n / 2
print ''.join(to_binary(0)) # 0
print ''.join(to_binary(1)) # 1
print ''.join(to_binary(15)) # 1111
print ''.join(to_binary(27)) # 11011
I get this problem in Leetcode:
https://leetcode.com/problems/reverse-bits/
So the input will be a decimal integer and I have to turn it into binary 32 bits.
And then I reverse it and turn it back to decimal.
For example:
Input:
8 (whose binary == 1000)
Output:
1 (whose binary == 0001)
Here is my code:
# n is input number
str1 = str('{0:0{1}b}'.format(n,32))
len_str = len(str1)
index_swap = len_str - 1
result = [0] * len_str
for i, char in enumerate(str1):
result[index_swap-i] = char
return int(str(''.join(result)),2)
If I run this code in Leetcode online Judge, I will get this error:
TypeError: sequence item 0: expected string, int found
This error is raised by the input 0.
I have no idea why it will raise this error. My code seems to works well!
result = [0] * len_str
len_str is an int but a string was expected.
What should happen in that Line? Maybe:
result = ['' for x in xrange(len_str)]
which initialize an empty string of size len_str
# There ...
a = 8
b = "{0:b}".format(8)[::-1]
print(type(b), b)
# and back again.
c = int(b[::-1], base=2)
print(type(c), c)
Output
<class 'str'> 0001
<class 'int'> 8
See also Reverse a string in Python