Je suis impliqué dans un projet où nous lions une API C en Jython (via Java). Nous avons rencontré des problèmes avec des valeurs non signées (puisque Java ne les supporte pas). Nous pouvons utiliser la conversion entre Java et C, mais passer de Jython à Java est une tâche plus difficile. J'ai écrit des fonctions de "casting" en Python. Ils convertissent un modèle binaire représentant une valeur signée ou non signée dans le même schéma de bits représentant le signe opposé.Importer des valeurs non signées de Jython, via Java, vers C et vice-versa
Par exemple:
>>> u2s(0xFFFFFFFF)
-1L
>>> hex(s2u(-1))
'0xffffffffL'
Y at-il une façon plus élégante pour gérer ce type de conversions de signe entre Jython et Java? Est-ce que quelqu'un a déjà essayé de le faire?
est ici l'ensemble du module:
__all__ = ['u2s', 's2u']
def u2s(v,width=32):
"""
Convert a bit pattern representing an unsigned value to the
SAME BIT PATTERN representing a signed value.
>>> u2s(0xFFFFFFFF)
-1L
>>> u2s(0x7FFFFFFF)
2147483647L
"""
msb = int("1" + ((width - 1) * '0'), 2)
msk = int("1" * width, 2)
nv = v & msk
if 0 < (msb & nv):
return -1 * ((nv^msk) + 1)
else:
return nv
def s2u(v,width=32):
"""
Convert a bit pattern representing a signed value to the
SAME BIT PATTERN representing an unsinged value.
>>> hex(s2u(-1))
'0xffffffffL'
>>> hex(s2u(1))
'0x1L'
"""
msk = int("1" * width, 2)
if 0 > v:
return msk & (((-1 * v)^msk) + 1)
else:
return msk & v
if __name__ == "__main__":
import doctest
doctest.testmod()
Je suis allé benchmarkée mon code VS la réponse acceptée dans Jython. La réponse acceptée est environ 1/3 meilleure! J'ai seulement testé la version avec des largeurs définies explicitement.
Modifier mon code fourni avec ce qui suit pour exécuter l'indice de référence pour vous-même:
def _u2s(v, width=32):
fmt = {8: "B", 16: "H", 32: "I", 64: "Q"}[width]
return struct.unpack(fmt.lower(), struct.pack(fmt, v))[0]
def _s2u(v, width=32):
fmt = {8: "B", 16: "H", 32: "I", 64: "Q"}[width]
return struct.unpack(fmt, struct.pack(fmt.lower(), v))[0]
if __name__ == "__main__":
import doctest
doctest.testmod()
import time
x = range(-1000000,1000000)
t1 = time.clock()
y = map(s2u, x)
t2 = time.clock()
print t2 - t1
_t1 = time.clock()
z = map(_s2u, x)
_t2 = time.clock()
print _t2 - _t1
J'espérais permettre de définir éventuellement la largeur. J'avais pris cela en compte. Je suppose que je pouvais seulement autoriser des largeurs prédéfinies. – John
@John, la dernière partie de ma réponse fonctionne pour n'importe quelle largeur –
@nibbler - Ah, merveilleux. Merci. – John