File Coverage

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