简体   繁体   中英

Why is simple XOR not working in Perl?

my $list = "1 3";
my @arr  = split " ", $list;
my $c    = $arr[0] ^ $arr[1];
print $c, "\n";

The above is giving an abnormal character.

It should give answer as 2, since 1 XOR 3 is 2.

^ considers the internal storage format of its operand to determine what action to perform.

>perl -E"say( 1^3 )"
2

>perl -E"say( '1'^'3' )"
☻

The latter xors each character of the strings.

>perl -E"say( chr( ord('1')^ord('3') ) )"
☻

You can force numification by adding zero.

>perl -E"@a = split(' ', '1 3'); say( (0+$a[0])^(0+$a[1]) )"
2

>perl -E"@a = map 0+$_, split(' ', '1 3'); say( $a[0]^$a[1] )"
2

Technically, you only need to make one of the operands numeric.

>perl -E"@a = split(' ', '1 3'); say( (0+$a[0])^$a[1] )"
2

>perl -E"@a = split(' ', '1 3'); say( $a[0]^(0+$a[1]) )"
2

Two problems here:

  • $c1 and $c2 are undefined at the start.
  • They're strings.

(I'll assume there's a bit missing, such that 'c1' and 'c2' get extracted as first/last element of the list, 1 and 3 respectively)

Try:

$list="1 2 3";
@arr=split(" ",$list);
$c=int($arr[0])^int($arr[2]);
print "$c";

the int function explicitly casts to a numeric value.

Perl v5.26 has a feature to force numeric context on the bitwise operators :

use v5.26;
use feature qw(bitwise);

my $list = "1 3";
my @arr  = split " ", $list;
my $c    = $arr[0] ^ $arr[1];
print $c, "\n";

Over time, perl has changed/improved it's handling of bitwise string operations.

The answer is not simple, and there are numeric, and bitwise xor operations in perl. I'll refer you to the Bitwise-String-Operators section of the manual. Note how they are now trying to address this "unpredictable behavior" by using the "bitwise" feature, new/experimental in Perl 5.22, stable in Perl 5.28 ( see brian d foy's article Make bitwise operators always use numeric context that he mentions in the comments below ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM