def unhack(me, nn):
return sum(n << i*me.piecewd for i, n in enumerate(nn))
-class QfConvert (object):
+class BaseQfConvert (object):
def __init__(me, p, wdseq):
me.p = p
me.wdseq = wdseq
else:
seq = map(int, arg.split(','))
print ";; piece widths = %r" % seq
- return QfConvert(p, seq)
+ return cls(p, seq)
def hack(me, n):
- if 2*n >= me.p: n -= p
+ if me.SIGNEDP and 2*n >= me.p: n -= me.p
nn = []
wds = cycle(me.wdseq)
while n:
wd = wds.next()
lim = 1 << wd; m = lim - 1
d = n&m; n >>= wd
- if d >= lim/2: d -= lim; n += 1
- nn.append(str(d))
+ if me.SIGNEDP and d >= lim/2: d -= lim; n += 1
+ nn.append(me.fmt(d))
return nn
def unhack(me, nn):
a = o = 0
if a < 0: a += me.p
return a
+class SignedQfConvert (BaseQfConvert):
+ SIGNEDP = True
+ def fmt(me, n): return str(n)
+
+class UnsignedQfConvert (BaseQfConvert):
+ SIGNEDP = False
+ def fmt(me, n): return '0x%x' % n
+
R_split = RX.compile(r',\s*|\s+')
def spliteval(arg): return map(eval, R_split.split(arg.strip()))
convmap = { 'scaf': ScafConvert,
'unscaf': ScafConvert,
- 'qf': QfConvert,
- 'unqf': QfConvert }
+ 'qf': SignedQfConvert,
+ 'unqf': SignedQfConvert,
+ 'uqf': UnsignedQfConvert,
+ 'unuqf': UnsignedQfConvert }
op = getarg()
cvt = convmap[op].parse()
if op.startswith('un'): prepare, conv, format = spliteval, cvt.unhack, str