File Coverage

blib/lib/Data/Integer.pm
Criterion Covered Total %
statement 625 626 99.8
branch 180 194 92.7
condition 33 42 78.5
subroutine 188 188 100.0
pod 74 74 100.0
total 1100 1124 97.8


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Data::Integer - details of the native integer data type
4              
5             =head1 SYNOPSIS
6              
7             use Data::Integer qw(natint_bits);
8              
9             $n = natint_bits;
10              
11             # and other constants; see text
12              
13             use Data::Integer qw(nint sint uint nint_is_sint nint_is_uint);
14              
15             $ni = nint($ni);
16             $si = sint($si);
17             $ui = uint($ui);
18             if(nint_is_sint($ni)) { ...
19             if(nint_is_uint($ni)) { ...
20              
21             use Data::Integer qw(
22             nint_sgn sint_sgn uint_sgn
23             nint_abs sint_abs uint_abs
24             nint_cmp sint_cmp uint_cmp
25             nint_min sint_min uint_min
26             nint_max sint_max uint_max
27             nint_neg sint_neg uint_neg
28             nint_add sint_add uint_add
29             nint_sub sint_sub uint_sub
30             );
31              
32             $sn = nint_sgn($ni);
33             $sn = sint_sgn($si);
34             $sn = uint_sgn($ui);
35             $ni = nint_abs($ni);
36             $si = sint_abs($si);
37             $ui = uint_abs($ui);
38             @sorted_nints = sort { nint_cmp($a, $b) } @nints;
39             @sorted_sints = sort { sint_cmp($a, $b) } @sints;
40             @sorted_uints = sort { uint_cmp($a, $b) } @uints;
41             $ni = nint_min($na, $nb);
42             $si = sint_min($sa, $sb);
43             $ui = uint_min($ua, $ub);
44             $ni = nint_max($na, $nb);
45             $si = sint_max($sa, $sb);
46             $ui = uint_max($ua, $ub);
47             $ni = nint_neg($ni);
48             $si = sint_neg($si);
49             $ui = uint_neg($ui);
50             $ni = nint_add($na, $nb);
51             $si = sint_add($sa, $sb);
52             $ui = uint_add($ua, $ub);
53             $ni = nint_sub($na, $nb);
54             $si = sint_sub($sa, $sb);
55             $ui = uint_sub($ua, $ub);
56              
57             use Data::Integer qw(
58             sint_shl uint_shl
59             sint_shr uint_shr
60             sint_rol uint_rol
61             sint_ror uint_ror
62             );
63              
64             $si = sint_shl($si, $dist);
65             $ui = uint_shl($ui, $dist);
66             $si = sint_shr($si, $dist);
67             $ui = uint_shr($ui, $dist);
68             $si = sint_rol($si, $dist);
69             $ui = uint_rol($ui, $dist);
70             $si = sint_ror($si, $dist);
71             $ui = uint_ror($ui, $dist);
72              
73             use Data::Integer qw(
74             nint_bits_as_sint nint_bits_as_uint
75             sint_bits_as_uint uint_bits_as_sint
76             );
77              
78             $si = nint_bits_as_sint($ni);
79             $ui = nint_bits_as_uint($ni);
80             $ui = sint_bits_as_uint($si);
81             $si = uint_bits_as_sint($ui);
82              
83             use Data::Integer qw(
84             sint_not uint_not
85             sint_and uint_and
86             sint_nand uint_nand
87             sint_andn uint_andn
88             sint_or uint_or
89             sint_nor uint_nor
90             sint_orn uint_orn
91             sint_xor uint_xor
92             sint_nxor uint_nxor
93             sint_mux uint_mux
94             );
95              
96             $si = sint_not($si);
97             $ui = uint_not($ui);
98             $si = sint_and($sa, $sb);
99             $ui = uint_and($ua, $ub);
100             $si = sint_nand($sa, $sb);
101             $ui = uint_nand($ua, $ub);
102             $si = sint_andn($sa, $sb);
103             $ui = uint_andn($ua, $ub);
104             $si = sint_or($sa, $sb);
105             $ui = uint_or($ua, $ub);
106             $si = sint_nor($sa, $sb);
107             $ui = uint_nor($ua, $ub);
108             $si = sint_orn($sa, $sb);
109             $ui = uint_orn($ua, $ub);
110             $si = sint_xor($sa, $sb);
111             $ui = uint_xor($ua, $ub);
112             $si = sint_nxor($sa, $sb);
113             $ui = uint_nxor($ua, $ub);
114             $si = sint_mux($sa, $sb, $sc);
115             $ui = uint_mux($ua, $ub, $uc);
116              
117             use Data::Integer qw(
118             sint_madd uint_madd
119             sint_msub uint_msub
120             sint_cadd uint_cadd
121             sint_csub uint_csub
122             sint_sadd uint_sadd
123             sint_ssub uint_ssub
124             );
125              
126             $si = sint_madd($sa, $sb);
127             $ui = uint_madd($ua, $ub);
128             $si = sint_msub($sa, $sb);
129             $ui = uint_msub($ua, $ub);
130             ($carry, $si) = sint_cadd($sa, $sb, $carry);
131             ($carry, $ui) = uint_cadd($ua, $ub, $carry);
132             ($carry, $si) = sint_csub($sa, $sb, $carry);
133             ($carry, $ui) = uint_csub($ua, $ub, $carry);
134             $si = sint_sadd($sa, $sb);
135             $ui = uint_sadd($ua, $ub);
136             $si = sint_ssub($sa, $sb);
137             $ui = uint_ssub($ua, $ub);
138              
139             use Data::Integer qw(natint_hex hex_natint);
140              
141             print natint_hex($value);
142             $value = hex_natint($string);
143              
144             =head1 DESCRIPTION
145              
146             This module is about the native integer numerical data type. A native
147             integer is one of the types of datum that can appear in the numeric part
148             of a Perl scalar. This module supplies constants describing the native
149             integer type.
150              
151             There are actually two native integer representations: signed and
152             unsigned. Both are handled by this module.
153              
154             =head1 NATIVE INTEGERS
155              
156             Each native integer format represents a value using binary place
157             value, with some fixed number of bits. The number of bits is the
158             same for both signed and unsigned representations. In each case
159             the least-significant bit has the value 1, the next 2, the next 4,
160             and so on. In the unsigned representation, this pattern continues up
161             to and including the most-significant bit, which for a 32-bit machine
162             therefore has the value 2^31 (2147483648). The unsigned format cannot
163             represent any negative numbers.
164              
165             In the signed format, the most-significant bit is exceptional, having
166             the negation of the value that it does in the unsigned format. Thus on
167             a 32-bit machine this has the value -2^31 (-2147483648). Values with
168             this bit set are negative, and those with it clear are non-negative;
169             this bit is also known as the "sign bit".
170              
171             It is usual in machine arithmetic to use one of these formats at a
172             time, for example to add two signed numbers yielding a signed result.
173             However, Perl has a trick: a scalar with a native integer value contains
174             an additional flag bit which indicates whether the signed or unsigned
175             format is being used. It is therefore possible to mix signed and unsigned
176             numbers in arithmetic, at some extra expense.
177              
178             =cut
179              
180             package Data::Integer;
181              
182 8     8   125860 { use 5.006; }
  8         25  
  8         309  
183 8     8   34 use warnings;
  8         11  
  8         255  
184 8     8   46 use strict;
  8         23  
  8         307  
185              
186 8     8   40 use Carp qw(croak);
  8         9  
  8         624  
187              
188             our $VERSION = "0.005";
189              
190 8     8   3613 use parent "Exporter";
  8         2085  
  8         33  
191             our @EXPORT_OK = qw(
192             natint_bits
193             min_nint max_nint min_natint max_natint
194             min_sint max_sint min_signed_natint max_signed_natint
195             min_uint max_uint min_unsigned_natint max_unsigned_natint
196             nint sint uint
197             nint_is_sint nint_is_uint
198             nint_sgn sint_sgn uint_sgn
199             nint_abs sint_abs uint_abs
200             nint_cmp sint_cmp uint_cmp
201             nint_min sint_min uint_min
202             nint_max sint_max uint_max
203             nint_neg sint_neg uint_neg
204             nint_add sint_add uint_add
205             nint_sub sint_sub uint_sub
206             sint_shl uint_shl
207             sint_shr uint_shr
208             sint_rol uint_rol
209             sint_ror uint_ror
210             nint_bits_as_sint nint_bits_as_uint
211             sint_bits_as_uint uint_bits_as_sint
212             sint_not uint_not
213             sint_and uint_and
214             sint_nand uint_nand
215             sint_andn uint_andn
216             sint_or uint_or
217             sint_nor uint_nor
218             sint_orn uint_orn
219             sint_xor uint_xor
220             sint_nxor uint_nxor
221             sint_mux uint_mux
222             sint_madd uint_madd
223             sint_msub uint_msub
224             sint_cadd uint_cadd
225             sint_csub uint_csub
226             sint_sadd uint_sadd
227             sint_ssub uint_ssub
228             natint_hex hex_natint
229             );
230              
231             =head1 CONSTANTS
232              
233             Each of the extreme-value constants has two names, a short one and a
234             long one. The short names are more convenient to use, but the long
235             names are clearer in a context where other similar constants exist.
236              
237             Due to the risks of Perl changing the behaviour of a native integer value
238             that has been involved in floating point arithmetic (see L),
239             the extreme-value constants are actually non-constant functions that
240             always return a fresh copy of the appropriate value. The returned value
241             is always a pure native integer value, unsullied by floating point or
242             string operations.
243              
244             =over
245              
246             =item natint_bits
247              
248             The width, in bits, of the native integer data types.
249              
250             =cut
251              
252             # Count the number of bits in native integers by repeatedly shifting a bit
253             # left until it turns into the sign bit. "use integer" forces the use of a
254             # signed integer representation.
255             BEGIN {
256 8     8   4500 use integer;
  8         61  
  8         29  
257 8     8   454 my $bit_count = 1;
258 8         12 my $test_bit = 1;
259 8         29 while($test_bit > 0) {
260 504         284 $bit_count += 1;
261 504         558 $test_bit <<= 1;
262             }
263 8         12 my $natint_bits = $bit_count;
264 8         253 *natint_bits = sub () { $natint_bits };
  0         0  
265             }
266              
267             =item min_nint
268              
269             =item min_natint
270              
271             The minimum representable value in either representation. This is
272             -2^(natint_bits - 1).
273              
274             =cut
275              
276             BEGIN {
277 8     8   36 my $min_nint = do { use integer; 1 << (natint_bits - 1) };
  8     8   12  
  8         72  
  8         340  
  8         11  
278 8     13117   561 *min_natint = *min_nint = sub() { my $ret = $min_nint };
  13117         46852  
279             }
280              
281             =item max_nint
282              
283             =item max_natint
284              
285             The maximum representable value in either representation. This is
286             2^natint_bits - 1.
287              
288             =cut
289              
290             BEGIN {
291 8     8   21 my $max_nint = ~0;
292 8     9167   242 *max_natint = *max_nint = sub() { my $ret = $max_nint };
  9167         22179  
293             }
294              
295             =item min_sint
296              
297             =item min_signed_natint
298              
299             The minimum representable value in the signed representation. This is
300             -2^(natint_bits - 1).
301              
302             =cut
303              
304 8     8   419 BEGIN { *min_signed_natint = *min_sint = \&min_nint; }
305              
306             =item max_sint
307              
308             =item max_signed_natint
309              
310             The maximum representable value in the signed representation. This is
311             2^(natint_bits - 1) - 1.
312              
313             =cut
314              
315             BEGIN {
316 8     8   20 my $max_sint = ~min_sint;
317 8     4427   540 *max_signed_natint = *max_sint = sub() { my $ret = $max_sint };
  4427         11547  
318             }
319              
320             =item min_uint
321              
322             =item min_unsigned_natint
323              
324             The minimum representable value in the unsigned representation.
325             This is zero.
326              
327             =cut
328              
329             BEGIN {
330 8     8   15 my $min_uint = 0;
331 8     4136   231 *min_unsigned_natint = *min_uint = sub() { my $ret = $min_uint };
  4136         11904  
332             }
333              
334             =item max_uint
335              
336             =item max_unsigned_natint
337              
338             The maximum representable value in the unsigned representation. This is
339             2^natint_bits - 1.
340              
341             =cut
342              
343 8     8   596 BEGIN { *max_unsigned_natint = *max_uint = \&max_nint; }
344              
345             =back
346              
347             =head1 FUNCTIONS
348              
349             Each "nint_", "sint_", or "uint_" function operates on one of the three
350             integer formats. "nint_" functions operate on Perl's union of signed
351             and unsigned; "sint_" functions operate on signed integers; and "uint_"
352             functions operate on unsigned integers. Except where indicated otherwise,
353             the function returns a value of its primary type.
354              
355             Parameters I, I, and I, where present, must be numbers of
356             the appropriate type: specifically, with a numerical value that can be
357             represented in that type. If there are multiple flavours of zero, due
358             to floating point funkiness, all zeroes are treated the same. Parameters
359             with other names have other requirements, explained with each function.
360              
361             The functions attempt to detect unsuitable arguments, and C if
362             an invalid argument is detected, but they can't notice some kinds of
363             incorrect argument. Generally, it is the caller's responsibility to
364             provide a sane numerical argument, and supplying an invalid argument will
365             cause mayhem. Only the numeric value of plain scalar arguments is used;
366             the string value is completely ignored, so dualvars are not a problem.
367              
368             =head2 Canonicalisation and classification
369              
370             These are basic glue functions.
371              
372             =over
373              
374             =item nint(A)
375              
376             =item sint(A)
377              
378             =item uint(A)
379              
380             These functions each take an argument in a specific integer format and
381             return its numerical value. This is the argument canonicalisation that is
382             performed by all of the functions in this module, presented in isolation.
383              
384             =cut
385              
386             sub nint($) {
387 4669     4669 1 6837 my $tval = $_[0];
388 4669 100 100     9937 croak "not a native integer"
      100        
389             unless int($tval) == $tval && $tval >= min_nint &&
390             $tval <= max_nint;
391 8 100   8   46 return ($tval = $_[0]) < 0 ? do { use integer; 0 | $_[0] } : 0 | $_[0];
  8         10  
  8         44  
  4666         8006  
  1587         2183  
392             }
393              
394             sub sint($) {
395 3930     3930 1 3958 my $tval = $_[0];
396 3930 100 100     7693 croak "not a signed native integer"
      100        
397             unless int($tval) == $tval && $tval >= min_sint &&
398             $tval <= max_sint;
399 8     8   823 my $val = do { use integer; 0 | $_[0] };
  8         12  
  8         22  
  3922         2801  
  3922         3547  
400             croak "not a signed native integer"
401 8 50 66 8   297 if $tval >= 0 && do { use integer; $val < 0 };
  8         9  
  8         22  
  3922         5396  
  2406         4078  
402 3922         5956 return $val;
403             }
404              
405             sub uint($) {
406 4135     4135 1 5578 my $tval = $_[0];
407 4135 100 100     8220 croak "not an unsigned native integer"
      100        
408             unless int($tval) == $tval && $tval >= min_uint &&
409             $tval <= max_uint;
410 4128         7432 return 0 | $_[0];
411             }
412              
413             =item nint_is_sint(A)
414              
415             Takes a native integer of either type. Returns a truth value indicating
416             whether this value can be exactly represented as a signed native integer.
417              
418             =cut
419              
420             sub nint_is_sint($) {
421 1314     1314 1 214457 my $val = nint($_[0]);
422             return (my $tval = $val) < 0 ||
423 8   66 8   903 do { use integer; ($val & min_sint) == 0 };
  8         14  
  8         22  
  1314         2341  
424             }
425              
426             =item nint_is_uint(A)
427              
428             Takes a native integer of either type. Returns a truth value indicating
429             whether this value can be exactly represented as an unsigned native
430             integer.
431              
432             =cut
433              
434 1099     1099 1 118949 sub nint_is_uint($) { nint($_[0]) >= 0 }
435              
436             =back
437              
438             =head2 Arithmetic
439              
440             These functions operate on numerical values rather than just bit patterns.
441             They will all C if the true numerical result doesn't fit into the
442             result format, rather than give a wrong answer.
443              
444             =over
445              
446             =item nint_sgn(A)
447              
448             =item sint_sgn(A)
449              
450             =item uint_sgn(A)
451              
452             Returns +1 if the argument is positive, 0 if the argument is zero,
453             or -1 if the argument is negative.
454              
455             =cut
456              
457 21     21 1 2099 sub nint_sgn($) { nint($_[0]) <=> 0 }
458              
459 8     8 1 773 sub sint_sgn($) { use integer; sint($_[0]) <=> 0 }
  8     8   9  
  8         21  
  8         27  
460              
461 8 100   8 1 326 sub uint_sgn($) { use integer; uint($_[0]) == 0 ? 0 : +1 }
  8     8   11  
  8         20  
  8         26  
462              
463             =item nint_abs(A)
464              
465             =item sint_abs(A)
466              
467             =item uint_abs(A)
468              
469             Absolute value (magnitude, discarding sign).
470              
471             =cut
472              
473             sub nint_abs($) {
474 21     21 1 33 my $a = nint($_[0]);
475 21 100       37 if((my $tval = $a) >= 0) {
    100          
476 14         27 return $a;
477 8     8   500 } elsif(do { use integer; $a == min_sint }) {
  8         10  
  8         30  
  7         10  
478 1         2 return 0 | min_sint;
479             } else {
480 8     8   246 use integer;
  8         13  
  8         18  
481 6         13 return -$a;
482             }
483             }
484              
485             sub sint_abs($) {
486 8     8 1 16 my $a = sint($_[0]);
487 8     8   409 use integer;
  8         10  
  8         32  
488 8 100       9 croak "integer overflow" if $a == min_sint;
489 7 100       15 return $a < 0 ? -$a : $a;
490             }
491              
492             *uint_abs = \&uint;
493              
494             =item nint_cmp(A, B)
495              
496             =item sint_cmp(A, B)
497              
498             =item uint_cmp(A, B)
499              
500             Arithmetic comparison. Returns -1, 0, or +1, indicating whether A is
501             less than, equal to, or greater than B.
502              
503             =cut
504              
505             sub nint_cmp($$) {
506 196     196 1 23994 my($a, $b) = (nint($_[0]), nint($_[1]));
507 196 100       278 if((my $ta = $a) < 0) {
508 70 100       91 if((my $tb = $b) < 0) {
509 8     8   827 use integer;
  8         13  
  8         21  
510 25         67 return $a <=> $b;
511             } else {
512 45         116 return -1;
513             }
514             } else {
515 126 100       153 if((my $tb = $b) < 0) {
516 45         121 return 1;
517             } else {
518 8     8   369 use integer;
  8         12  
  8         27  
519 81         110 return ($a ^ min_sint) <=> ($b ^ min_sint);
520             }
521             }
522             }
523              
524 8     8 1 406 sub sint_cmp($$) { use integer; sint($_[0]) <=> sint($_[1]) }
  8     121   11  
  8         21  
  121         377  
525              
526             sub uint_cmp($$) {
527 8     8   401 use integer;
  8         10  
  8         19  
528 81     81 1 336 return (uint($_[0]) ^ min_sint) <=> (uint($_[1]) ^ min_sint);
529             }
530              
531             =item nint_min(A, B)
532              
533             =item sint_min(A, B)
534              
535             =item uint_min(A, B)
536              
537             Arithmetic minimum. Returns the arithmetically lesser of the two
538             arguments.
539              
540             =cut
541              
542             sub nint_min($$) {
543 196     196 1 404 my($a, $b) = (nint($_[0]), nint($_[1]));
544 196 100       292 if((my $ta = $a) < 0) {
545 70 100       93 if((my $tb = $b) < 0) {
546 8     8   737 use integer;
  8         11  
  8         23  
547 25 100       64 return $a < $b ? $a : $b;
548             } else {
549 45         78 return $a;
550             }
551             } else {
552 126 100       182 if((my $tb = $b) < 0) {
553 45         82 return $b;
554             } else {
555 8     8   328 use integer;
  8         10  
  8         20  
556 81 100       105 return ($a ^ min_sint) < ($b ^ min_sint) ? $a : $b;
557             }
558             }
559             }
560              
561             sub sint_min($$) {
562 121     121 1 237 my($a, $b) = (sint($_[0]), sint($_[1]));
563 8     8   678 use integer;
  8         13  
  8         26  
564 121 100       239 return $a < $b ? $a : $b;
565             }
566              
567             sub uint_min($$) {
568 81     81 1 155 my($a, $b) = (uint($_[0]), uint($_[1]));
569 8     8   446 use integer;
  8         12  
  8         30  
570 81 100       109 return ($a ^ min_sint) < ($b ^ min_sint) ? $a : $b;
571             }
572              
573             =item nint_max(A, B)
574              
575             =item sint_max(A, B)
576              
577             =item uint_max(A, B)
578              
579             Arithmetic maximum. Returns the arithmetically greater of the two
580             arguments.
581              
582             =cut
583              
584             sub nint_max($$) {
585 196     196 1 50328 my($a, $b) = (nint($_[0]), nint($_[1]));
586 196 100       282 if((my $ta = $a) < 0) {
587 70 100       93 if((my $tb = $b) < 0) {
588 8     8   654 use integer;
  8         10  
  8         21  
589 25 100       78 return $a < $b ? $b : $a;
590             } else {
591 45         72 return $b;
592             }
593             } else {
594 126 100       172 if((my $tb = $b) < 0) {
595 45         81 return $a;
596             } else {
597 8     8   312 use integer;
  8         9  
  8         22  
598 81 100       108 return ($a ^ min_sint) < ($b ^ min_sint) ? $b : $a;
599             }
600             }
601             }
602              
603             sub sint_max($$) {
604 121     121 1 27858 my($a, $b) = (sint($_[0]), sint($_[1]));
605 8     8   551 use integer;
  8         9  
  8         28  
606 121 100       226 return $a < $b ? $b : $a;
607             }
608              
609             sub uint_max($$) {
610 81     81 1 23454 my($a, $b) = (uint($_[0]), uint($_[1]));
611 8     8   475 use integer;
  8         10  
  8         24  
612 81 100       112 return ($a ^ min_sint) < ($b ^ min_sint) ? $b : $a;
613             }
614              
615             =item nint_neg(A)
616              
617             =item sint_neg(A)
618              
619             =item uint_neg(A)
620              
621             Negation: returns -A.
622              
623             =cut
624              
625             sub nint_neg($) {
626 12     12 1 19 my $a = nint($_[0]);
627 12 100       17 if((my $ta = $a) <= 0) {
628 8     8   578 return 0 | do { use integer; -$a };
  8         8  
  8         23  
  5         5  
  5         13  
629             } else {
630 8     8   193 use integer;
  8         10  
  8         20  
631 7         8 my $neg = -$a;
632 7 100       237 croak "integer overflow" if $neg >= 0;
633 4         6 return $neg;
634             }
635             }
636              
637             sub sint_neg($) {
638 8     8 1 3293 my $a = sint($_[0]);
639 8     8   553 use integer;
  8         12  
  8         396  
640 8 100       10 croak "integer overflow" if $a == min_sint;
641 7         10 return -$a;
642             }
643              
644             sub uint_neg($) {
645 8     8   460 use integer;
  8         10  
  8         25  
646 8 100   8 1 14 croak "integer overflow" unless uint($_[0]) == 0;
647 1         2 return my $zero = 0;
648             }
649              
650             =item nint_add(A, B)
651              
652             =item sint_add(A, B)
653              
654             =item uint_add(A, B)
655              
656             Addition: returns A + B.
657              
658             =cut
659              
660             sub nint_add($$) {
661 252     252 1 91824 my($a, $b) = (nint($_[0]), nint($_[1]));
662 252 100       351 if((my $ta = $a) < 0) {
663 89 100       106 if((my $tb = $b) < 0) {
664 8     8   815 use integer;
  8         15  
  8         23  
665 34         30 my $r = $a + $b;
666 34 100       1335 croak "integer overflow" if $r > $a;
667 18         31 return $r;
668             } else {
669 8     8   360 use integer;
  8         10  
  8         24  
670 55         50 my $r = $a + $b;
671 8 100   8   209 $r = do { no integer; 0 | $r } if $r < $a;
  8         10  
  8         24  
  55         83  
  7         9  
672 55         92 return $r;
673             }
674             } else {
675 163 100       278 if((my $tb = $b) < 0) {
676 8     8   291 use integer;
  8         13  
  8         56  
677 55         51 my $r = $a + $b;
678 8 100   8   207 $r = do { no integer; 0 | $r } if $r < $b;
  8         16  
  8         23  
  55         72  
  7         8  
679 55         97 return $r;
680             } else {
681 8     8   266 use integer;
  8         8  
  8         23  
682 108         107 my $r = $a + $b;
683 108 100       135 croak "integer overflow"
684             if ($r ^ min_sint) < ($a ^ min_sint);
685 8     8   385 return do { no integer; 0 | $r };
  8         11  
  8         24  
  68         67  
  68         125  
686             }
687             }
688             }
689              
690             sub sint_add($$) {
691 148     148 1 30348 my($a, $b) = (sint($_[0]), sint($_[1]));
692 8     8   635 use integer;
  8         13  
  8         21  
693 148         158 my $r = $a + $b;
694 148 100       3472 croak "integer overflow" if $b < 0 ? $r > $a : $r < $a;
    100          
695 112         169 return $r;
696             }
697              
698             sub uint_add($$) {
699 108     108 1 25789 my($a, $b) = (uint($_[0]), uint($_[1]));
700 8     8   669 use integer;
  8         10  
  8         23  
701 108         99 my $r = $a + $b;
702 108 100       117 croak "integer overflow" if ($r ^ min_sint) < ($a ^ min_sint);
703 8     8   363 return do { no integer; 0 | $r };
  8         9  
  8         22  
  68         57  
  68         108  
704             }
705              
706             =item nint_sub(A, B)
707              
708             =item sint_sub(A, B)
709              
710             =item uint_sub(A, B)
711              
712             Subtraction: returns A - B.
713              
714             =cut
715              
716             sub nint_sub($$) {
717 234     234 1 41590 my($a, $b) = (nint($_[0]), nint($_[1]));
718 234 100       367 if((my $ta = $a) < 0) {
    100          
719 63 100       81 if((my $tb = $b) < 0) {
    100          
720 8     8   631 use integer;
  8         9  
  8         50  
721 31         56 return $a - $b;
722             } elsif(!($b & min_sint)) {
723 8     8   318 use integer;
  8         10  
  8         20  
724 22         24 my $r = $a - $b;
725 22 100       760 croak "integer overflow" if $r >= 0;
726 13         25 return $r;
727             } else {
728 10         787 croak "integer overflow";
729             }
730             } elsif(!($a & min_sint)) {
731 106 100       171 if((my $tb = $b) < 0) {
    100          
732 8     8   577 return 0 | do { use integer; $a - $b };
  8         11  
  8         23  
  35         33  
  35         72  
733             } elsif(!($b & min_sint)) {
734 8     8   324 use integer;
  8         9  
  8         20  
735 47         94 return $a - $b;
736             } else {
737 8     8   266 use integer;
  8         8  
  8         18  
738 24         24 my $r = $a - $b;
739 24 100       821 croak "integer overflow" if $r >= 0;
740 14         25 return $r;
741             }
742             } else {
743 65 100       151 if((my $tb = $b) < 0) {
    100          
744 8     8   416 use integer;
  8         11  
  8         24  
745 16         17 my $r = $a - $b;
746 16 100       736 croak "integer overflow" if $r >= 0;
747 8     8   322 return do { no integer; 0 | $r };
  8         10  
  8         21  
  7         5  
  7         14  
748             } elsif(!($b & min_sint)) {
749 8     8   251 return 0 | do { use integer; $a - $b };
  8         10  
  8         20  
  31         33  
  31         70  
750             } else {
751 8     8   298 use integer;
  8         19  
  8         19  
752 18         37 return $a - $b;
753             }
754             }
755             }
756              
757             sub sint_sub($$) {
758 135     135 1 505 my($a, $b) = (sint($_[0]), sint($_[1]));
759 8     8   606 use integer;
  8         11  
  8         25  
760 135         125 my $r = $a - $b;
761 135 100       2069 croak "integer overflow" if $b > 0 ? $r > $a : $r < $a;
    100          
762 112         142 return $r;
763             }
764              
765             sub uint_sub($$) {
766 120     120 1 495 my($a, $b) = (uint($_[0]), uint($_[1]));
767 8     8   651 use integer;
  8         11  
  8         20  
768 120         126 my $r = $a - $b;
769 120 100       119 croak "integer overflow" if ($r ^ min_sint) > ($a ^ min_sint);
770 8     8   367 return do { no integer; 0 | $r };
  8         10  
  8         21  
  68         65  
  68         108  
771             }
772              
773             =back
774              
775             =head2 Bit shifting
776              
777             These functions all operate on the bit patterns representing integers,
778             mostly ignoring the numerical values represented. In most cases the
779             results for particular numerical arguments are influenced by the word
780             size, because that determines where a bit being left-shifted will drop
781             off the end of the word and where a bit will be shifted in during a
782             rightward shift.
783              
784             With the exception of rightward shifts (see below), each pair of
785             functions performs exactly the same operations on the bit sequences.
786             There inevitably can't be any functions here that operate on Perl's union
787             of signed and unsigned; you must choose, by which function you call,
788             which type the result is to be tagged as.
789              
790             =over
791              
792             =item sint_shl(A, DIST)
793              
794             =item uint_shl(A, DIST)
795              
796             Bitwise left shift (towards more-significant bits). I is the
797             distance to shift, in bits, and must be an integer in the range [0,
798             natint_bits). Zeroes are shifted in from the right.
799              
800             =cut
801              
802             sub sint_shl($$) {
803 21     21 1 47 my($val, $dist) = @_;
804 21         25 $dist = uint($dist);
805 21 50       35 croak "shift distance exceeds word size" if $dist >= natint_bits;
806 8     8   697 use integer;
  8         8  
  8         24  
807 21         50 return sint($val) << $dist;
808             }
809              
810             sub uint_shl($$) {
811 21     21 1 4212 my($val, $dist) = @_;
812 21         32 $dist = uint($dist);
813 21 50       30 croak "shift distance exceeds word size" if $dist >= natint_bits;
814 8     8   562 no integer;
  8         10  
  8         54  
815 21         25 return uint($val) << $dist;
816             }
817              
818             =item sint_shr(A, DIST)
819              
820             =item uint_shr(A, DIST)
821              
822             Bitwise right shift (towards less-significant bits). I is the
823             distance to shift, in bits, and must be an integer in the range [0,
824             natint_bits).
825              
826             When performing an unsigned right shift, zeroes are shifted in from the
827             left. A signed right shift is different: the sign bit gets duplicated,
828             so right-shifting a negative number always gives a negative result.
829              
830             =cut
831              
832             sub sint_shr($$) {
833 17     17 1 3437 my($val, $dist) = @_;
834 17         27 $dist = uint($dist);
835 17 50       25 croak "shift distance exceeds word size" if $dist >= natint_bits;
836 8     8   562 use integer;
  8         12  
  8         24  
837 17         21 return sint($val) >> $dist;
838             }
839              
840             sub uint_shr($$) {
841 17     17 1 3617 my($val, $dist) = @_;
842 17         25 $dist = uint($dist);
843 17 50       32 croak "shift distance exceeds word size" if $dist >= natint_bits;
844 8     8   682 no integer;
  8         12  
  8         30  
845 17         20 return uint($val) >> $dist;
846             }
847              
848             =item sint_rol(A, DIST)
849              
850             =item uint_rol(A, DIST)
851              
852             Bitwise left rotation (towards more-significant bits, with the
853             most-significant bit wrapping round to the least-significant bit).
854             I is the distance to rotate, in bits, and must be an integer in
855             the range [0, natint_bits).
856              
857             =cut
858              
859             sub sint_rol($$) {
860 21     21 1 57 my($val, $dist) = @_;
861 21         25 $dist = uint($dist);
862 21 50       35 croak "shift distance exceeds word size" if $dist >= natint_bits;
863 21         29 $val = sint($val);
864 21 100       45 return $val if $dist == 0;
865 17         22 my $low_val = $val >> (natint_bits - $dist);
866 8     8   767 use integer;
  8         9  
  8         45  
867 17         38 return $low_val | ($val << $dist);
868             }
869              
870             sub uint_rol($$) {
871 21     21 1 4119 my($val, $dist) = @_;
872 21         28 $dist = uint($dist);
873 21 50       38 croak "shift distance exceeds word size" if $dist >= natint_bits;
874 21         28 $val = uint($val);
875 21 100       50 return $val if $dist == 0;
876 17         35 return ($val >> (natint_bits - $dist)) | ($val << $dist);
877             }
878              
879             =item sint_ror(A, DIST)
880              
881             =item uint_ror(A, DIST)
882              
883             Bitwise right rotation (towards less-significant bits, with the
884             least-significant bit wrapping round to the most-significant bit).
885             I is the distance to rotate, in bits, and must be an integer in
886             the range [0, natint_bits).
887              
888             =cut
889              
890             sub sint_ror($$) {
891 21     21 1 28 my($val, $dist) = @_;
892 21         30 $dist = uint($dist);
893 21 50       29 croak "shift distance exceeds word size" if $dist >= natint_bits;
894 21         32 $val = sint($val);
895 21 100       42 return $val if $dist == 0;
896 17         17 my $low_val = $val >> $dist;
897 8     8   1456 use integer;
  8         13  
  8         26  
898 17         34 return $low_val | ($val << (natint_bits - $dist));
899             }
900              
901             sub uint_ror($$) {
902 21     21 1 31 my($val, $dist) = @_;
903 21         23 $dist = uint($dist);
904 21 50       36 croak "shift distance exceeds word size" if $dist >= natint_bits;
905 21         28 $val = uint($val);
906 21 100       41 return $val if $dist == 0;
907 17         49 return ($val >> $dist) | ($val << (natint_bits - $dist));
908             }
909              
910             =back
911              
912             =head2 Format conversion
913              
914             These functions convert between the various native integer formats
915             by reinterpreting the bit patterns used to represent the integers.
916             The bit pattern remains unchanged; its meaning changes, and so the
917             numerical value changes. Perl scalars preserve the numerical value,
918             rather than just the bit pattern, so from the Perl point of view these
919             are functions that change numbers into other numbers.
920              
921             =over
922              
923             =item nint_bits_as_sint(A)
924              
925             Converts a native integer of either type to a signed integer, by
926             reinterpreting the bits. The most-significant bit (whether a sign bit
927             or not) becomes a sign bit.
928              
929             =cut
930              
931 8     8 1 936 sub nint_bits_as_sint($) { use integer; nint($_[0]) | 0 }
  8     13   11  
  8         26  
  13         2711  
932              
933             =item nint_bits_as_uint(A)
934              
935             Converts a native integer of either type to an unsigned integer, by
936             reinterpreting the bits. The most-significant bit (whether a sign bit
937             or not) becomes an ordinary most-significant bit.
938              
939             =cut
940              
941 8     8 1 394 sub nint_bits_as_uint($) { no integer; nint($_[0]) | 0 }
  8     13   9  
  8         22  
  13         34  
942              
943             =item sint_bits_as_uint(A)
944              
945             Converts a signed integer to an unsigned integer, by reinterpreting
946             the bits. The sign bit becomes an ordinary most-significant bit.
947              
948             =cut
949              
950 8     8 1 317 sub sint_bits_as_uint($) { no integer; sint($_[0]) | 0 }
  8     9   9  
  8         23  
  9         34  
951              
952             =item uint_bits_as_sint(A)
953              
954             Converts an unsigned integer to a signed integer, by reinterpreting
955             the bits. The most-significant bit becomes a sign bit.
956              
957             =cut
958              
959 8     8 1 334 sub uint_bits_as_sint($) { use integer; uint($_[0]) | 0 }
  8     578   9  
  8         22  
  578         1280  
960              
961             =back
962              
963             =head2 Bitwise operations
964              
965             These functions all operate on the bit patterns representing integers,
966             completely ignoring the numerical values represented. They are mostly
967             not influenced by the word size, in the sense that they will produce
968             the same numerical result for the same numerical arguments regardless
969             of word size. However, a few are affected by the word size: those on
970             unsigned operands that return a non-zero result if given zero arguments.
971              
972             Each pair of functions performs exactly the same operations on the bit
973             sequences. There inevitably can't be any functions here that operate on
974             Perl's union of signed and unsigned; you must choose, by which function
975             you call, which type the result is to be tagged as.
976              
977             =over
978              
979             =item sint_not(A)
980              
981             =item uint_not(A)
982              
983             Bitwise complement (NOT).
984              
985             =cut
986              
987 8     8 1 336 sub sint_not($) { use integer; ~sint($_[0]) }
  8     8   9  
  8         25  
  8         18  
988              
989 8     8 1 302 sub uint_not($) { no integer; ~uint($_[0]) }
  8     8   8  
  8         31  
  8         565  
990              
991             =item sint_and(A, B)
992              
993             =item uint_and(A, B)
994              
995             Bitwise conjunction (AND).
996              
997             =cut
998              
999 8     8 1 303 sub sint_and($$) { use integer; sint($_[0]) & sint($_[1]) }
  8     16   12  
  8         189  
  16         41  
1000              
1001 8     8 1 382 sub uint_and($$) { no integer; uint($_[0]) & uint($_[1]) }
  8     16   11  
  8         24  
  16         1762  
1002              
1003             =item sint_nand(A, B)
1004              
1005             =item uint_nand(A, B)
1006              
1007             Bitwise inverted conjunction (NAND).
1008              
1009             =cut
1010              
1011 8     8 1 426 sub sint_nand($$) { use integer; ~(sint($_[0]) & sint($_[1])) }
  8     16   10  
  8         26  
  16         50  
1012              
1013 8     8 1 359 sub uint_nand($$) { no integer; ~(uint($_[0]) & uint($_[1])) }
  8     16   9  
  8         21  
  16         2077  
1014              
1015             =item sint_andn(A, B)
1016              
1017             =item uint_andn(A, B)
1018              
1019             Bitwise conjunction with inverted argument (A AND (NOT B)).
1020              
1021             =cut
1022              
1023 8     8 1 388 sub sint_andn($$) { use integer; sint($_[0]) & ~sint($_[1]) }
  8     8   11  
  8         53  
  8         21  
1024              
1025 8     8 1 394 sub uint_andn($$) { no integer; uint($_[0]) & ~uint($_[1]) }
  8     8   10  
  8         22  
  8         1394  
1026              
1027             =item sint_or(A, B)
1028              
1029             =item uint_or(A, B)
1030              
1031             Bitwise disjunction (OR).
1032              
1033             =cut
1034              
1035 8     8 1 377 sub sint_or($$) { use integer; sint($_[0]) | sint($_[1]) }
  8     16   11  
  8         23  
  16         31  
1036              
1037 8     8 1 409 sub uint_or($$) { no integer; uint($_[0]) | uint($_[1]) }
  8     16   10  
  8         29  
  16         1369  
1038              
1039             =item sint_nor(A, B)
1040              
1041             =item uint_nor(A, B)
1042              
1043             Bitwise inverted disjunction (NOR).
1044              
1045             =cut
1046              
1047 8     8 1 363 sub sint_nor($$) { use integer; ~(sint($_[0]) | sint($_[1])) }
  8     16   13  
  8         23  
  16         31  
1048              
1049 8     8 1 386 sub uint_nor($$) { no integer; ~(uint($_[0]) | uint($_[1])) }
  8     16   14  
  8         22  
  16         1315  
1050              
1051             =item sint_orn(A, B)
1052              
1053             =item uint_orn(A, B)
1054              
1055             Bitwise disjunction with inverted argument (A OR (NOT B)).
1056              
1057             =cut
1058              
1059 8     8 1 402 sub sint_orn($$) { use integer; sint($_[0]) | ~sint($_[1]) }
  8     8   22  
  8         20  
  8         21  
1060              
1061 8     8 1 396 sub uint_orn($$) { no integer; uint($_[0]) | ~uint($_[1]) }
  8     8   10  
  8         19  
  8         1276  
1062              
1063             =item sint_xor(A, B)
1064              
1065             =item uint_xor(A, B)
1066              
1067             Bitwise symmetric difference (XOR).
1068              
1069             =cut
1070              
1071 8     8 1 509 sub sint_xor($$) { use integer; sint($_[0]) ^ sint($_[1]) }
  8     16   8  
  8         23  
  16         31  
1072              
1073 8     8 1 351 sub uint_xor($$) { no integer; uint($_[0]) ^ uint($_[1]) }
  8     16   9  
  8         31  
  16         1198  
1074              
1075             =item sint_nxor(A, B)
1076              
1077             =item uint_nxor(A, B)
1078              
1079             Bitwise symmetric similarity (NXOR).
1080              
1081             =cut
1082              
1083 8     8 1 374 sub sint_nxor($$) { use integer; ~(sint($_[0]) ^ sint($_[1])) }
  8     16   8  
  8         19  
  16         33  
1084              
1085 8     8 1 354 sub uint_nxor($$) { no integer; ~(uint($_[0]) ^ uint($_[1])) }
  8     16   11  
  8         28  
  16         1156  
1086              
1087             =item sint_mux(A, B, C)
1088              
1089             =item uint_mux(A, B, C)
1090              
1091             Bitwise multiplex. The output has a bit from B wherever A has a 1 bit,
1092             and a bit from C wherever A has a 0 bit. That is, the result is (A AND B)
1093             OR ((NOT A) AND C).
1094              
1095             =cut
1096              
1097             sub sint_mux($$$) {
1098 10     10 1 23 my $a = sint($_[0]);
1099 8     8   551 use integer;
  8         10  
  8         25  
1100 10         14 return ($a & sint($_[1])) | (~$a & sint($_[2]));
1101             }
1102              
1103             sub uint_mux($$$) {
1104 10     10 1 696 my $a = uint($_[0]);
1105 8     8   613 no integer;
  8         9  
  8         23  
1106 10         13 return ($a & uint($_[1])) | (~$a & uint($_[2]));
1107             }
1108              
1109             =back
1110              
1111             =head2 Machine arithmetic
1112              
1113             These functions perform arithmetic operations that are inherently
1114             influenced by the word size. They always produce a well-defined output
1115             if given valid inputs. There inevitably can't be any functions here
1116             that operate on Perl's union of signed and unsigned; you must choose,
1117             by which function you call, which type the result is to be tagged as.
1118              
1119             =over
1120              
1121             =item sint_madd(A, B)
1122              
1123             =item uint_madd(A, B)
1124              
1125             Modular addition. The result for unsigned addition is (A + B)
1126             mod 2^natint_bits. The signed version behaves similarly, but with a
1127             different result range.
1128              
1129             =cut
1130              
1131 8     8 1 442 sub sint_madd($$) { use integer; sint($_[0]) + sint($_[1]) }
  8     172   10  
  8         22  
  172         453  
1132              
1133 8     8 1 375 sub uint_madd($$) { 0 | do { use integer; uint($_[0]) + uint($_[1]) } }
  8     172   11  
  8         24  
  172         22599  
  172         322  
1134              
1135             =item sint_msub(A, B)
1136              
1137             =item uint_msub(A, B)
1138              
1139             Modular subtraction. The result for unsigned subtraction is (A - B)
1140             mod 2^natint_bits. The signed version behaves similarly, but with a
1141             different result range.
1142              
1143             =cut
1144              
1145 8     8 1 381 sub sint_msub($$) { use integer; sint($_[0]) - sint($_[1]) }
  8     172   9  
  8         24  
  172         327  
1146              
1147 8     8 1 412 sub uint_msub($$) { 0 | do { use integer; uint($_[0]) - uint($_[1]) } }
  8     172   8  
  8         22  
  172         157  
  172         304  
1148              
1149             =item sint_cadd(A, B, CARRY_IN)
1150              
1151             =item uint_cadd(A, B, CARRY_IN)
1152              
1153             Addition with carry. Two word arguments (A and B) and an input carry
1154             bit (CARRY_IN, which must have the value 0 or 1) are all added together.
1155             Returns a list of two items: an output carry and an output word (of the
1156             same signedness as the inputs). Precisely, the output list (CARRY_OUT,
1157             R) is such that CARRY_OUT*2^natint_bits + R = A + B + CARRY_IN.
1158              
1159             =cut
1160              
1161             sub sint_cadd($$$) {
1162 196     196 1 75017 my($a, $b, $cin) = map { sint($_) } @_;
  588         637  
1163 8     8   548 use integer;
  8         11  
  8         21  
1164 196 50 66     445 croak "invalid carry" unless $cin == 0 || $cin == 1;
1165 196         191 my $r = $a + $b + $cin;
1166 196 100       369 my $cout = $b < 0 ? $r > $a ? -1 : 0 : $r < $a ? +1 : 0;
    100          
    100          
1167 196         274 return ($cout, $r);
1168             }
1169              
1170             sub uint_cadd($$$) {
1171 172     172 1 62475 my($a, $b, $cin) = map { uint($_) } @_;
  516         564  
1172 8     8   742 use integer;
  8         11  
  8         24  
1173 172 50 66     380 croak "invalid carry" unless $cin == 0 || $cin == 1;
1174 172         148 my $r = $a + $b;
1175 172 100       185 my $cout = ($r ^ min_sint) < ($a ^ min_sint) ? 1 : 0;
1176 172 100       213 if($cin) {
1177 86         59 $r += 1;
1178 86 100       122 $cout = 1 if $r == 0;
1179             }
1180 8     8   506 return ($cout, do { no integer; 0 | $r });
  8         10  
  8         27  
  172         89  
  172         254  
1181             }
1182              
1183             =item sint_csub(A, B, CARRY_IN)
1184              
1185             =item uint_csub(A, B, CARRY_IN)
1186              
1187             Subtraction with carry (borrow). The second word argument (B) and
1188             an input carry bit (CARRY_IN, which must have the value 0 or 1) are
1189             subtracted from the first word argument (A). Returns a list of two
1190             items: an output carry and an output word (of the same signedness as
1191             the inputs). Precisely, the output list (CARRY_OUT, R) is such that R -
1192             CARRY_OUT*2^natint_bits = A - B - CARRY_IN.
1193              
1194             =cut
1195              
1196             sub sint_csub($$$) {
1197 196     196 1 76760 my($a, $b, $cin) = map { sint($_) } @_;
  588         645  
1198 8     8   626 use integer;
  8         12  
  8         23  
1199 196 50 66     558 croak "invalid carry" unless $cin == 0 || $cin == 1;
1200 196         177 my $r = $a - $b - $cin;
1201 196 100       471 my $cout = $b < 0 ? $r < $a ? -1 : 0 : $r > $a ? +1 : 0;
    100          
    100          
1202 196         340 return ($cout, $r);
1203             }
1204              
1205             sub uint_csub($$$) {
1206 172     172 1 64270 my($a, $b, $cin) = map { uint($_) } @_;
  516         534  
1207 8     8   1006 use integer;
  8         10  
  8         32  
1208 172 50 66     395 croak "invalid carry" unless $cin == 0 || $cin == 1;
1209 172         128 my $r = $a - $b;
1210 172 100       190 my $cout = ($r ^ min_sint) > ($a ^ min_sint) ? 1 : 0;
1211 172 100       256 if($cin) {
1212 86 100       115 $cout = 1 if $r == 0;
1213 86         65 $r -= 1;
1214             }
1215 8     8   507 return ($cout, do { no integer; 0 | $r });
  8         10  
  8         22  
  172         124  
  172         255  
1216             }
1217              
1218             =item sint_sadd(A, B)
1219              
1220             =item uint_sadd(A, B)
1221              
1222             Saturating addition. The result is A + B if that will fit into the result
1223             format, otherwise the minimum or maximum value of the result format is
1224             returned depending on the direction in which the addition overflowed.
1225              
1226             =cut
1227              
1228             sub sint_sadd($$) {
1229 98     98 1 8318 my($a, $b) = map { sint($_) } @_;
  196         216  
1230 8     8   563 use integer;
  8         10  
  8         26  
1231 98         89 my $r = $a + $b;
1232 98 100       100 if($b < 0) {
1233 39 100       52 $r = min_sint if $r > $a;
1234             } else {
1235 59 100       97 $r = max_sint if $r < $a;
1236             }
1237 98         139 return $r;
1238             }
1239              
1240             sub uint_sadd($$) {
1241 86     86 1 7424 my($a, $b) = map { uint($_) } @_;
  172         178  
1242 8     8   768 use integer;
  8         9  
  8         24  
1243 86         63 my $r = $a + $b;
1244 86 100       80 $r = max_uint if ($r ^ min_sint) < ($a ^ min_sint);
1245 8     8   346 return do { no integer; 0 | $r };
  8         12  
  8         22  
  86         59  
  86         131  
1246             }
1247              
1248             =item sint_ssub(A, B)
1249              
1250             =item uint_ssub(A, B)
1251              
1252             Saturating subtraction. The result is A - B if that will fit into the
1253             result format, otherwise the minimum or maximum value of the result
1254             format is returned depending on the direction in which the subtraction
1255             overflowed.
1256              
1257             =cut
1258              
1259             sub sint_ssub($$) {
1260 92     92 1 16195 my($a, $b) = map { sint($_) } @_;
  184         179  
1261 8     8   483 use integer;
  8         10  
  8         24  
1262 92         83 my $r = $a - $b;
1263 92 100       106 if($b >= 0) {
1264 50 100       65 $r = min_sint if $r > $a;
1265             } else {
1266 42 100       52 $r = max_sint if $r < $a;
1267             }
1268 92         122 return $r;
1269             }
1270              
1271             sub uint_ssub($$) {
1272 89     89 1 15265 my($a, $b) = map { uint($_) } @_;
  178         172  
1273 8     8   771 use integer;
  8         13  
  8         23  
1274 89 100       96 my $r = ($a ^ min_sint) <= ($b ^ min_sint) ? 0 : $a - $b;
1275 8     8   342 return do { no integer; 0 | $r };
  8         9  
  8         32  
  89         62  
  89         190  
1276             }
1277              
1278             =back
1279              
1280             =head2 String conversion
1281              
1282             =over
1283              
1284             =item natint_hex(VALUE)
1285              
1286             VALUE must be a native integer value. The function encodes VALUE in
1287             hexadecimal, returning that representation as a string. Specifically,
1288             the output is of the form "IB<0x>I", where "I" is the sign
1289             and "I" is a sequence of hexadecimal digits.
1290              
1291             =cut
1292              
1293             sub natint_hex($) {
1294 9     9 1 24 my $val = nint($_[0]);
1295 9         15 my $sgn = nint_sgn($val);
1296 9         17 $val = nint_abs($val);
1297 9         13 my $digits = "";
1298 9         10 my $i = (natint_bits+3) >> 2;
1299 9         14 for(; $i >= 7; $i -= 7) {
1300 18         53 $digits = sprintf("%07x", $val & 0xfffffff).$digits;
1301 18         36 $val >>= 28;
1302             }
1303 9         20 for(; $i--; ) {
1304 18         30 $digits = sprintf("%01x", $val & 0xf).$digits;
1305 18         30 $val >>= 4;
1306             }
1307 9 100       86 return ($sgn == -1 ? "-" : "+")."0x".$digits;
1308             }
1309              
1310             =item hex_natint(STRING)
1311              
1312             Generates and returns a native integer value from a string encoding it in
1313             hexadecimal. Specifically, the input format is "[I][B<0x>]I",
1314             where "I" is the sign and "I" is a sequence of one or more
1315             hexadecimal digits. The input is interpreted case insensitively.
1316             If the value given in the string cannot be exactly represented in the
1317             native integer type, the function Cs.
1318              
1319             The core Perl function C (see L) does a similar job
1320             to this function, but differs in several ways. Principally, C
1321             doesn't handle negative values, and it gives the wrong answer for values
1322             that don't fit into the native integer type. In Perl 5.6 it also gives
1323             the wrong answer for values that don't fit into the native floating
1324             point type. It also doesn't enforce strict syntax on the input string.
1325              
1326             =cut
1327              
1328             my %hexdigit_value;
1329             {
1330 8     8   1374 use integer;
  8         12  
  8         58  
1331             $hexdigit_value{chr(ord("0") + $_)} = $_ foreach 0..9;
1332             $hexdigit_value{chr(ord("a") + $_)} = 10+$_ foreach 0..5;
1333             $hexdigit_value{chr(ord("A") + $_)} = 10+$_ foreach 0..5;
1334             }
1335              
1336             sub hex_natint($) {
1337 103     103 1 30785 my($str) = @_;
1338 103 50       484 $str =~ /\A([-+]?)(?:0x)?([0-9a-f]+)\z/i
1339             or croak "bad syntax for hexadecimal integer value";
1340 103         232 my($sign, $digits) = ($1, $2);
1341 8     8   1155 use integer;
  8         20  
  8         34  
1342 103         191 $digits =~ /\A0*/g;
1343 103 100       190 return my $zero = 0 if $digits =~ /\G\z/gc;
1344 100         141 $digits =~ /\G(.)/g;
1345 100         142 my $value = $hexdigit_value{$1};
1346 100         127 my $bits_to_go = (length($digits)-pos($digits)) << 2;
1347 100 100 33     6078 croak "integer value too large"
      66        
1348             if $bits_to_go >= natint_bits ||
1349             ($bits_to_go + 4 > natint_bits &&
1350             (max_uint >> $bits_to_go) < $value);
1351 31         62 while($digits =~ /\G(.)/g) {
1352 252         429 $value = ($value << 4) | $hexdigit_value{$1};
1353             }
1354 31 100       52 if($sign eq "-") {
1355 15         14 $value = -$value;
1356 15 100       741 croak "integer value too large" if $value >= 0;
1357 7         23 return $value;
1358             } else {
1359 8     8   1160 no integer;
  8         10  
  8         22  
1360 16         45 return 0 | $value;
1361             }
1362             }
1363              
1364             =back
1365              
1366             =head1 BUGS
1367              
1368             In Perl 5.6, when a native integer scalar is used in any arithmetic other
1369             than specifically integer arithmetic, it gets partially transformed into
1370             a floating point scalar. Even if its numerical value can be represented
1371             exactly in floating point, so that floating point arithmetic uses the
1372             correct numerical value, some operations are affected by the floatness.
1373             In particular, the stringification of the scalar doesn't necessarily
1374             represent its exact value if it is tagged as floating point.
1375              
1376             Because of this transforming behaviour, if you need to stringify a native
1377             integer it is best to ensure that it doesn't get used in any non-integer
1378             arithmetic first. If an integer scalar must be used in standard Perl
1379             arithmetic, it may be copied first and the copy operated upon to avoid
1380             causing side effects on the original. If an integer scalar might have
1381             already been transformed, it can be cleaned by passing it through the
1382             canonicalisation function C. The functions in this module all
1383             avoid modifying their arguments, and always return pristine integers.
1384              
1385             Perl 5.8+ still internally modifies integer scalars in the same
1386             circumstances, but seems to have corrected all the misbehaviour that
1387             resulted from it.
1388              
1389             Also in Perl 5.6, default Perl arithmetic doesn't necessarily work
1390             correctly on native integers. (This is part of the motivation for
1391             the myriad arithmetic functions in this module.) Default arithmetic
1392             here is strictly floating point, so if there are native integers that
1393             cannot be exactly represented in floating point then the arithmetic will
1394             approximate the values before operating on them. Perl 5.8+ attempts to
1395             use native integer operations where possible in its default arithmetic,
1396             but as of Perl 5.8.8 it doesn't always succeed. For reliable integer
1397             arithmetic, integer operations must still be requested explicitly.
1398              
1399             =head1 SEE ALSO
1400              
1401             L,
1402             L,
1403             L
1404              
1405             =head1 AUTHOR
1406              
1407             Andrew Main (Zefram)
1408              
1409             =head1 COPYRIGHT
1410              
1411             Copyright (C) 2007, 2010, 2015 Andrew Main (Zefram)
1412              
1413             =head1 LICENSE
1414              
1415             This module is free software; you can redistribute it and/or modify it
1416             under the same terms as Perl itself.
1417              
1418             =cut
1419              
1420             1;