Question

Wasn't sure about the best title for this one...

Anyway, I'm trying to convert some Python code to TCL and have the following snippet in Python:

ctypes.c_int32(x << c).value

Which returns: -293412352

I've written this in TCL as a simple expr:

expr {$x << $c}

But this returns: 162915344896

In both cases, x = 1272776132 and c = 7

Is there a way to format or convert the TCL value so it's represented the same as the Python value?

Était-ce utile?

La solution

It depends on precisely what you want to do, which in turn depends on the wider context of the algorithm. Tcl uses a model of integers based on bignums (even though it usually uses smaller types for the implementation) which means that we need to reinterpret the value.

binary scan [binary format i [expr {$x << $c}]] i theResult
# theResult = -293412352

However, if you just want to mask the bits off and don't really want the sign changing, do this:

set theResult [expr {($x << $c) & 0xffffffff}]
# theResult = 4001554944

(All results checked with Tcl 8.5 and Tcl 8.6 on a 64-bit platform, but any variation on a 32-bit platform would be considered to be a critical bug; Tcl's fairly careful in its numeric code to create the illusion of numbers not having a finite number of bits available, except in the binary command — as used above — and in the format and scan commands, though not in a way that's useful here.)

Autres conseils

The problem you are having is a bit-width issue. To hold the output of your TCL expression, you need a 64-bit integer, not a 32-bit integer.

# Wrong
In [7]: C.c_int32(x<<c)
Out[7]: c_int(-293412352)

# Correct
In [9]: C.c_int64(x<<c)
Out[9]: c_long(162915344896)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top