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?

Was it helpful?

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.)

OTHER TIPS

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top