Вопрос

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?

Это было полезно?

Решение

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

Другие советы

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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top