1 | #!./perl
|
---|
2 |
|
---|
3 | #
|
---|
4 | # test the bit operators '&', '|', '^', '~', '<<', and '>>'
|
---|
5 | #
|
---|
6 |
|
---|
7 | BEGIN {
|
---|
8 | chdir 't' if -d 't';
|
---|
9 | @INC = '../lib';
|
---|
10 | require "./test.pl";
|
---|
11 | require Config;
|
---|
12 | }
|
---|
13 |
|
---|
14 | # Tests don't have names yet.
|
---|
15 | # If you find tests are failing, please try adding names to tests to track
|
---|
16 | # down where the failure is, and supply your new names as a patch.
|
---|
17 | # (Just-in-time test naming)
|
---|
18 | plan tests => 49;
|
---|
19 |
|
---|
20 | # numerics
|
---|
21 | ok ((0xdead & 0xbeef) == 0x9ead);
|
---|
22 | ok ((0xdead | 0xbeef) == 0xfeef);
|
---|
23 | ok ((0xdead ^ 0xbeef) == 0x6042);
|
---|
24 | ok ((~0xdead & 0xbeef) == 0x2042);
|
---|
25 |
|
---|
26 | # shifts
|
---|
27 | ok ((257 << 7) == 32896);
|
---|
28 | ok ((33023 >> 7) == 257);
|
---|
29 |
|
---|
30 | # signed vs. unsigned
|
---|
31 | ok ((~0 > 0 && do { use integer; ~0 } == -1));
|
---|
32 |
|
---|
33 | my $bits = 0;
|
---|
34 | for (my $i = ~0; $i; $i >>= 1) { ++$bits; }
|
---|
35 | my $cusp = 1 << ($bits - 1);
|
---|
36 |
|
---|
37 |
|
---|
38 | ok (($cusp & -1) > 0 && do { use integer; $cusp & -1 } < 0);
|
---|
39 | ok (($cusp | 1) > 0 && do { use integer; $cusp | 1 } < 0);
|
---|
40 | ok (($cusp ^ 1) > 0 && do { use integer; $cusp ^ 1 } < 0);
|
---|
41 | ok ((1 << ($bits - 1)) == $cusp &&
|
---|
42 | do { use integer; 1 << ($bits - 1) } == -$cusp);
|
---|
43 | ok (($cusp >> 1) == ($cusp / 2) &&
|
---|
44 | do { use integer; abs($cusp >> 1) } == ($cusp / 2));
|
---|
45 |
|
---|
46 | $Aaz = chr(ord("A") & ord("z"));
|
---|
47 | $Aoz = chr(ord("A") | ord("z"));
|
---|
48 | $Axz = chr(ord("A") ^ ord("z"));
|
---|
49 |
|
---|
50 | # short strings
|
---|
51 | is (("AAAAA" & "zzzzz"), ($Aaz x 5));
|
---|
52 | is (("AAAAA" | "zzzzz"), ($Aoz x 5));
|
---|
53 | is (("AAAAA" ^ "zzzzz"), ($Axz x 5));
|
---|
54 |
|
---|
55 | # long strings
|
---|
56 | $foo = "A" x 150;
|
---|
57 | $bar = "z" x 75;
|
---|
58 | $zap = "A" x 75;
|
---|
59 | # & truncates
|
---|
60 | is (($foo & $bar), ($Aaz x 75 ));
|
---|
61 | # | does not truncate
|
---|
62 | is (($foo | $bar), ($Aoz x 75 . $zap));
|
---|
63 | # ^ does not truncate
|
---|
64 | is (($foo ^ $bar), ($Axz x 75 . $zap));
|
---|
65 |
|
---|
66 | #
|
---|
67 | is ("ok \xFF\xFF\n" & "ok 19\n", "ok 19\n");
|
---|
68 | is ("ok 20\n" | "ok \0\0\n", "ok 20\n");
|
---|
69 | is ("o\000 \0001\000" ^ "\000k\0002\000\n", "ok 21\n");
|
---|
70 |
|
---|
71 | #
|
---|
72 | is ("ok \x{FF}\x{FF}\n" & "ok 22\n", "ok 22\n");
|
---|
73 | is ("ok 23\n" | "ok \x{0}\x{0}\n", "ok 23\n");
|
---|
74 | is ("o\x{0} \x{0}4\x{0}" ^ "\x{0}k\x{0}2\x{0}\n", "ok 24\n");
|
---|
75 |
|
---|
76 | #
|
---|
77 | is (sprintf("%vd", v4095 & v801), 801);
|
---|
78 | is (sprintf("%vd", v4095 | v801), 4095);
|
---|
79 | is (sprintf("%vd", v4095 ^ v801), 3294);
|
---|
80 |
|
---|
81 | #
|
---|
82 | is (sprintf("%vd", v4095.801.4095 & v801.4095), '801.801');
|
---|
83 | is (sprintf("%vd", v4095.801.4095 | v801.4095), '4095.4095.4095');
|
---|
84 | is (sprintf("%vd", v801.4095 ^ v4095.801.4095), '3294.3294.4095');
|
---|
85 | #
|
---|
86 | is (sprintf("%vd", v120.300 & v200.400), '72.256');
|
---|
87 | is (sprintf("%vd", v120.300 | v200.400), '248.444');
|
---|
88 | is (sprintf("%vd", v120.300 ^ v200.400), '176.188');
|
---|
89 | #
|
---|
90 | my $a = v120.300;
|
---|
91 | my $b = v200.400;
|
---|
92 | $a ^= $b;
|
---|
93 | is (sprintf("%vd", $a), '176.188');
|
---|
94 | my $a = v120.300;
|
---|
95 | my $b = v200.400;
|
---|
96 | $a |= $b;
|
---|
97 | is (sprintf("%vd", $a), '248.444');
|
---|
98 |
|
---|
99 | #
|
---|
100 | # UTF8 ~ behaviour
|
---|
101 | #
|
---|
102 |
|
---|
103 | my $Is_EBCDIC = (ord('A') == 193) ? 1 : 0;
|
---|
104 |
|
---|
105 | my @not36;
|
---|
106 |
|
---|
107 | for (0x100...0xFFF) {
|
---|
108 | $a = ~(chr $_);
|
---|
109 | if ($Is_EBCDIC) {
|
---|
110 | push @not36, sprintf("%#03X", $_)
|
---|
111 | if $a ne chr(~$_) or length($a) != 1;
|
---|
112 | }
|
---|
113 | else {
|
---|
114 | push @not36, sprintf("%#03X", $_)
|
---|
115 | if $a ne chr(~$_) or length($a) != 1 or ~$a ne chr($_);
|
---|
116 | }
|
---|
117 | }
|
---|
118 | is (join (', ', @not36), '');
|
---|
119 |
|
---|
120 | my @not37;
|
---|
121 |
|
---|
122 | for my $i (0xEEE...0xF00) {
|
---|
123 | for my $j (0x0..0x120) {
|
---|
124 | $a = ~(chr ($i) . chr $j);
|
---|
125 | if ($Is_EBCDIC) {
|
---|
126 | push @not37, sprintf("%#03X %#03X", $i, $j)
|
---|
127 | if $a ne chr(~$i).chr(~$j) or
|
---|
128 | length($a) != 2;
|
---|
129 | }
|
---|
130 | else {
|
---|
131 | push @not37, sprintf("%#03X %#03X", $i, $j)
|
---|
132 | if $a ne chr(~$i).chr(~$j) or
|
---|
133 | length($a) != 2 or
|
---|
134 | ~$a ne chr($i).chr($j);
|
---|
135 | }
|
---|
136 | }
|
---|
137 | }
|
---|
138 | is (join (', ', @not37), '');
|
---|
139 |
|
---|
140 | SKIP: {
|
---|
141 | skip "EBCDIC" if $Is_EBCDIC;
|
---|
142 | is (~chr(~0), "\0");
|
---|
143 | }
|
---|
144 |
|
---|
145 |
|
---|
146 | my @not39;
|
---|
147 |
|
---|
148 | for my $i (0x100..0x120) {
|
---|
149 | for my $j (0x100...0x120) {
|
---|
150 | push @not39, sprintf("%#03X %#03X", $i, $j)
|
---|
151 | if ~(chr($i)|chr($j)) ne (~chr($i)&~chr($j));
|
---|
152 | }
|
---|
153 | }
|
---|
154 | is (join (', ', @not39), '');
|
---|
155 |
|
---|
156 | my @not40;
|
---|
157 |
|
---|
158 | for my $i (0x100..0x120) {
|
---|
159 | for my $j (0x100...0x120) {
|
---|
160 | push @not40, sprintf("%#03X %#03X", $i, $j)
|
---|
161 | if ~(chr($i)&chr($j)) ne (~chr($i)|~chr($j));
|
---|
162 | }
|
---|
163 | }
|
---|
164 | is (join (', ', @not40), '');
|
---|
165 |
|
---|
166 |
|
---|
167 | # More variations on 19 and 22.
|
---|
168 | is ("ok \xFF\x{FF}\n" & "ok 41\n", "ok 41\n");
|
---|
169 | is ("ok \x{FF}\xFF\n" & "ok 42\n", "ok 42\n");
|
---|
170 |
|
---|
171 | # Tests to see if you really can do casts negative floats to unsigned properly
|
---|
172 | $neg1 = -1.0;
|
---|
173 | ok (~ $neg1 == 0);
|
---|
174 | $neg7 = -7.0;
|
---|
175 | ok (~ $neg7 == 6);
|
---|
176 |
|
---|
177 |
|
---|
178 | $a = "\0\x{100}"; chop($a);
|
---|
179 | ok(utf8::is_utf8($a)); # make sure UTF8 flag is still there
|
---|
180 | $a = ~$a;
|
---|
181 | is($a, "\xFF", "~ works with utf-8");
|
---|
182 |
|
---|
183 | # [rt.perl.org 33003]
|
---|
184 | # This would cause a segfault without malloc wrap
|
---|
185 | SKIP: {
|
---|
186 | skip "No malloc wrap checks" unless $Config::Config{usemallocwrap};
|
---|
187 | like( runperl(prog => 'eval q($#a>>=1); print 1'), "^1\n?" );
|
---|
188 | }
|
---|
189 |
|
---|
190 | # [perl #37616] Bug in &= (string) and/or m//
|
---|
191 | {
|
---|
192 | $a = "aa";
|
---|
193 | $a &= "a";
|
---|
194 | ok($a =~ /a+$/, 'ASCII "a" is NUL-terminated');
|
---|
195 |
|
---|
196 | $b = "bb\x{100}";
|
---|
197 | $b &= "b";
|
---|
198 | ok($b =~ /b+$/, 'Unicode "b" is NUL-terminated');
|
---|
199 | }
|
---|