[expr] bit-wise "and" operator, dual of [|]
Arguments must be integers, result is an integer.
Bit ''n'' of the result is 1 if bit ''n'' of each argument is 1. Otherwise, bit ''n'' of the result is 0.
For negative arguments, we use the extended definition of [~] that '''[~]$a[==]-1-$a'''.
There are then the following cases:
%| Case | Result |%
&| $a[>=]0,$b>=0 | Ordinary bitwise '''&''' |&
&| $a>=0,$b[<]0 | `$a&$b == $a & ~(~$b)` ''Contrapositive law'' <<br>> `$a&$b == $a & ~ (-1-$b)` ''Extended definition of [~]'' <<br>> Since -1-$b is positive, $a & ~(-1-$b) can be evaluated in bitwise fashion. |&
&| $a<0,$b>=0 | Commute to ($b & $a) and use the calculation above |&
&| $a<0,$b<0 | `$a&$b == ~ (~$a <<pipe>> ~$b)` ''De Morgan's Law'' <<br>> `$a&$b == ~ ((-1-$a) <<pipe>> (-1-$b))` ''Extended definition of [~]'' <<br>> `$a&$b == -1-((-1-$a) <<pipe>> (-1-$b))` ''Extended definition of [~]'' <<br>> Since [-]1-$a and -1-$b are both positive, the expression ((-1-$a) [<<pipe>>] (-1-$b)) can be evaluated in the ordinary bitwise fashion. |&
For logical/short-cut "and" use the [&&] operator.
----
**Precedence**
[AMG]: Be wary of the precedence of this operator! Like [&&], it has lower precedence than the comparison operators. For more information on why, read the section "Neonatal C" found at [https://cmwww.bell-labs.com/cm/cusr/who/dmr/www/chist.html].
%|Expression |Result|Comment |%
&|expr 5&2==2 |1 |expression without parentheses|&
&|expr 5&(2==2)|1 |actual behavior of Tcl and [C]|&
&|expr (5&2)==2|0 |naively expected behavior |&
----
**Convert negative integer to hexadecimal?**
'''[jennylv] - 2012-08-07 16:15:14'''
I want to convert signed integer to 32-bit hexadecimal.
The following works fine for positive integer:
======
format %.8x $the_decimal_value
======
But for negative integer, I got 64-bit hexadecimal.
For example 99 is converted to 00000063, but -81 is converted to ffffffffffffffaf.
Anyone know how to get 32-bit hexadecimal fro negative integer?
Thanks in advance!
[AMG]: The %.8x means to pad to eight characters only if narrower than eight to begin with. You want to truncate the value. What you're looking for is the [&] operator. Try this:
======
% format %.8x [expr {$the_decimal_value & 0xffffffff}]
======
'''[jennylv] - 2012-08-07 16:28:19'''
Thanks so much! That works fine:)
<<categories>> Operator