1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* Long (arbitrary precision) integer object implementation */
27 /* XXX The functional organization of this file is terrible */
29 #include "allobjects.h"
30 #include "longintrepr.h"
35 #define ABS(x) ((x) < 0 ? -(x) : (x))
38 static longobject
*long_normalize
PROTO((longobject
*));
39 static longobject
*mul1
PROTO((longobject
*, wdigit
));
40 static longobject
*muladd1
PROTO((longobject
*, wdigit
, wdigit
));
41 static longobject
*divrem1
PROTO((longobject
*, wdigit
, digit
*));
42 static object
*long_format
PROTO((object
*aa
, int base
));
44 static int ticker
; /* XXX Could be shared with ceval? */
46 #define SIGCHECK(block) \
49 if (sigcheck()) { block; } \
52 /* Normalize (remove leading zeros from) a long int object.
53 Doesn't attempt to free the storage--in most cases, due to the nature
54 of the algorithms used, this could save at most be one word anyway. */
58 register longobject
*v
;
60 int j
= ABS(v
->ob_size
);
63 while (i
> 0 && v
->ob_digit
[i
-1] == 0)
66 v
->ob_size
= (v
->ob_size
< 0) ? -(i
) : i
;
70 /* Allocate a new long int object with size digits.
71 Return NULL and set exception if we run out of memory. */
77 return NEWVAROBJ(longobject
, &Longtype
, size
);
80 /* Create a new long int object from a C long int */
86 /* Assume a C long fits in at most 3 'digits' */
87 /* XXX On 64 bit machines this isn't true!!! */
88 longobject
*v
= alloclongobject(3);
92 v
->ob_size
= -(v
->ob_size
);
94 v
->ob_digit
[0] = ival
& MASK
;
95 v
->ob_digit
[1] = (ival
>> SHIFT
) & MASK
;
96 v
->ob_digit
[2] = ((unsigned long)ival
>> (2*SHIFT
)) & MASK
;
97 v
= long_normalize(v
);
102 /* Create a new long int object from a C double */
106 dnewlongobject(double dval
)
114 int i
, ndig
, expo
, neg
;
120 frac
= frexp(dval
, &expo
); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
122 return newlongobject(0L);
123 ndig
= (expo
-1) / SHIFT
+ 1; /* Number of 'digits' in result */
124 v
= alloclongobject(ndig
);
127 frac
= ldexp(frac
, (expo
-1) % SHIFT
+ 1);
128 for (i
= ndig
; --i
>= 0; ) {
129 long bits
= (long)frac
;
130 v
->ob_digit
[i
] = bits
;
131 frac
= frac
- (double)bits
;
132 frac
= ldexp(frac
, SHIFT
);
135 v
->ob_size
= -(v
->ob_size
);
139 /* Get a C long int from a long int object.
140 Returns -1 and sets an error condition if overflow occurs. */
146 register longobject
*v
;
150 if (vv
== NULL
|| !is_longobject(vv
)) {
154 v
= (longobject
*)vv
;
164 x
= (x
<< SHIFT
) + v
->ob_digit
[i
];
165 if ((x
>> SHIFT
) != prev
) {
166 err_setstr(OverflowError
,
167 "long int too long to convert");
174 /* Get a C double from a long int object. No overflow check. */
180 register longobject
*v
;
182 double multiplier
= (double) (1L << SHIFT
);
185 if (vv
== NULL
|| !is_longobject(vv
)) {
189 v
= (longobject
*)vv
;
198 x
= x
*multiplier
+ (double)v
->ob_digit
[i
];
203 /* Multiply by a single digit, ignoring the sign. */
210 return muladd1(a
, n
, (digit
)0);
213 /* Multiply by a single digit and add a single digit, ignoring the sign. */
221 int size_a
= ABS(a
->ob_size
);
222 longobject
*z
= alloclongobject(size_a
+1);
223 twodigits carry
= extra
;
228 for (i
= 0; i
< size_a
; ++i
) {
229 carry
+= (twodigits
)a
->ob_digit
[i
] * n
;
230 z
->ob_digit
[i
] = carry
& MASK
;
233 z
->ob_digit
[i
] = carry
;
234 return long_normalize(z
);
237 /* Divide a long integer by a digit, returning both the quotient
238 (as function result) and the remainder (through *prem).
239 The sign of a is ignored; n should not be zero. */
247 int size
= ABS(a
->ob_size
);
252 assert(n
> 0 && n
<= MASK
);
253 z
= alloclongobject(size
);
256 for (i
= size
; --i
>= 0; ) {
257 rem
= (rem
<< SHIFT
) + a
->ob_digit
[i
];
258 z
->ob_digit
[i
] = rem
/n
;
262 return long_normalize(z
);
265 /* Convert a long int object to a string, using a given conversion base.
266 Return a string object.
267 If base is 8 or 16, add the proper prefix '0' or '0x'.
268 External linkage: used in bltinmodule.c by hex() and oct(). */
271 long_format(aa
, base
)
275 register longobject
*a
= (longobject
*)aa
;
278 int size_a
= ABS(a
->ob_size
);
283 if (a
== NULL
|| !is_longobject(a
)) {
287 assert(base
>= 2 && base
<= 36);
289 /* Compute a rough upper bound for the length of the string */
296 i
= 6 + (size_a
*SHIFT
+ bits
-1) / bits
;
297 str
= (stringobject
*) newsizedstringobject((char *)0, i
);
300 p
= GETSTRINGVALUE(str
) + i
;
309 longobject
*temp
= divrem1(a
, (digit
)base
, &rem
);
319 assert(p
> GETSTRINGVALUE(str
));
328 } while (ABS(a
->ob_size
) != 0);
334 else if (base
== 16) {
338 else if (base
!= 10) {
340 *--p
= '0' + base
%10;
342 *--p
= '0' + base
/10;
346 if (p
!= GETSTRINGVALUE(str
)) {
347 char *q
= GETSTRINGVALUE(str
);
350 } while ((*q
++ = *p
++) != '\0');
352 resizestring((object
**)&str
, (int) (q
- GETSTRINGVALUE(str
)));
354 return (object
*)str
;
358 /* Convert a string to a long int object, in a given base.
359 Base zero implies a default depending on the number.
360 External linkage: used in compile.c and stropmodule.c. */
367 return long_escan(str
, (char **)NULL
, base
);
372 long_escan(str
, pend
, base
)
380 if (base
!= 0 && base
< 2 || base
> 36) {
381 err_setstr(ValueError
, "invalid base for long literal");
384 while (*str
!= '\0' && isspace(Py_CHARMASK(*str
)))
388 else if (*str
== '-') {
392 while (*str
!= '\0' && isspace(Py_CHARMASK(*str
)))
397 else if (str
[1] == 'x' || str
[1] == 'X')
402 if (base
== 16 && str
[0] == '0' && (str
[1] == 'x' || str
[1] == 'X'))
404 z
= alloclongobject(0);
405 for ( ; z
!= NULL
; ++str
) {
411 else if (*str
>= 'a')
413 else if (*str
>= 'A')
415 if (k
< 0 || k
>= base
)
417 temp
= muladd1(z
, (digit
)base
, (digit
)k
);
421 if (sign
< 0 && z
!= NULL
&& z
->ob_size
!= 0)
422 z
->ob_size
= -(z
->ob_size
);
428 static longobject
*x_divrem
PROTO((longobject
*, longobject
*, longobject
**));
429 static object
*long_pos
PROTO((longobject
*));
430 static long_divrem
PROTO((longobject
*, longobject
*,
431 longobject
**, longobject
**));
433 /* Long division with remainder, top-level routine */
436 long_divrem(a
, b
, pdiv
, prem
)
441 int size_a
= ABS(a
->ob_size
), size_b
= ABS(b
->ob_size
);
445 err_setstr(ZeroDivisionError
, "long division or modulo");
448 if (size_a
< size_b
||
450 a
->ob_digit
[size_a
-1] < b
->ob_digit
[size_b
-1]) {
452 *pdiv
= alloclongobject(0);
454 *prem
= (longobject
*) a
;
459 z
= divrem1(a
, b
->ob_digit
[0], &rem
);
462 *prem
= (longobject
*) newlongobject((long)rem
);
465 z
= x_divrem(a
, b
, prem
);
470 The quotient z has the sign of a*b;
471 the remainder r has the sign of a,
473 if ((a
->ob_size
< 0) != (b
->ob_size
< 0))
474 z
->ob_size
= -(z
->ob_size
);
475 if (a
->ob_size
< 0 && (*prem
)->ob_size
!= 0)
476 (*prem
)->ob_size
= -((*prem
)->ob_size
);
481 /* Unsigned long division with remainder -- the algorithm */
484 x_divrem(v1
, w1
, prem
)
488 int size_v
= ABS(v1
->ob_size
), size_w
= ABS(w1
->ob_size
);
489 digit d
= (twodigits
)BASE
/ (w1
->ob_digit
[size_w
-1] + 1);
490 longobject
*v
= mul1(v1
, d
);
491 longobject
*w
= mul1(w1
, d
);
495 if (v
== NULL
|| w
== NULL
) {
501 assert(size_v
>= size_w
&& size_w
> 1); /* Assert checks by div() */
502 assert(v
->ob_refcnt
== 1); /* Since v will be used as accumulator! */
503 assert(size_w
== ABS(w
->ob_size
)); /* That's how d was calculated */
505 size_v
= ABS(v
->ob_size
);
506 a
= alloclongobject(size_v
- size_w
+ 1);
508 for (j
= size_v
, k
= a
->ob_size
-1; a
!= NULL
&& k
>= 0; --j
, --k
) {
509 digit vj
= (j
>= size_v
) ? 0 : v
->ob_digit
[j
];
511 stwodigits carry
= 0;
519 if (vj
== w
->ob_digit
[size_w
-1])
522 q
= (((twodigits
)vj
<< SHIFT
) + v
->ob_digit
[j
-1]) /
523 w
->ob_digit
[size_w
-1];
525 while (w
->ob_digit
[size_w
-2]*q
>
527 ((twodigits
)vj
<< SHIFT
)
529 - q
*w
->ob_digit
[size_w
-1]
534 for (i
= 0; i
< size_w
&& i
+k
< size_v
; ++i
) {
535 twodigits z
= w
->ob_digit
[i
] * q
;
536 digit zz
= z
>> SHIFT
;
537 carry
+= v
->ob_digit
[i
+k
] - z
+ ((twodigits
)zz
<< SHIFT
);
538 v
->ob_digit
[i
+k
] = carry
& MASK
;
539 carry
= (carry
>> SHIFT
) - zz
;
543 carry
+= v
->ob_digit
[i
+k
];
544 v
->ob_digit
[i
+k
] = 0;
551 a
->ob_digit
[k
] = q
-1;
553 for (i
= 0; i
< size_w
&& i
+k
< size_v
; ++i
) {
554 carry
+= v
->ob_digit
[i
+k
] + w
->ob_digit
[i
];
555 v
->ob_digit
[i
+k
] = carry
& MASK
;
564 a
= long_normalize(a
);
565 *prem
= divrem1(v
, d
, &d
);
566 /* d receives the (unused) remainder */
580 static void long_dealloc
PROTO((object
*));
581 static object
*long_repr
PROTO((object
*));
582 static int long_compare
PROTO((longobject
*, longobject
*));
583 static long long_hash
PROTO((longobject
*));
585 static object
*long_add
PROTO((longobject
*, longobject
*));
586 static object
*long_sub
PROTO((longobject
*, longobject
*));
587 static object
*long_mul
PROTO((longobject
*, longobject
*));
588 static object
*long_div
PROTO((longobject
*, longobject
*));
589 static object
*long_mod
PROTO((longobject
*, longobject
*));
590 static object
*long_divmod
PROTO((longobject
*, longobject
*));
591 static object
*long_pow
PROTO((longobject
*, longobject
*, longobject
*));
592 static object
*long_neg
PROTO((longobject
*));
593 static object
*long_pos
PROTO((longobject
*));
594 static object
*long_abs
PROTO((longobject
*));
595 static int long_nonzero
PROTO((longobject
*));
596 static object
*long_invert
PROTO((longobject
*));
597 static object
*long_lshift
PROTO((longobject
*, longobject
*));
598 static object
*long_rshift
PROTO((longobject
*, longobject
*));
599 static object
*long_and
PROTO((longobject
*, longobject
*));
600 static object
*long_xor
PROTO((longobject
*, longobject
*));
601 static object
*long_or
PROTO((longobject
*, longobject
*));
614 return long_format(v
, 10);
623 if (a
->ob_size
!= b
->ob_size
) {
624 if (ABS(a
->ob_size
) == 0 && ABS(b
->ob_size
) == 0)
627 sign
= a
->ob_size
- b
->ob_size
;
630 int i
= ABS(a
->ob_size
);
631 while (--i
>= 0 && a
->ob_digit
[i
] == b
->ob_digit
[i
])
636 sign
= (int)a
->ob_digit
[i
] - (int)b
->ob_digit
[i
];
641 return sign
< 0 ? -1 : sign
> 0 ? 1 : 0;
651 /* This is designed so that Python ints and longs with the
652 same value hash to the same value, otherwise comparisons
653 of mapping keys will turn out weird */
662 /* Force a 32-bit circular shift */
663 x
= ((x
<< SHIFT
) & ~MASK
) | ((x
>> (32-SHIFT
)) & MASK
);
673 /* Add the absolute values of two long integers. */
675 static longobject
*x_add
PROTO((longobject
*, longobject
*));
680 int size_a
= ABS(a
->ob_size
), size_b
= ABS(b
->ob_size
);
685 /* Ensure a is the larger of the two: */
686 if (size_a
< size_b
) {
687 { longobject
*temp
= a
; a
= b
; b
= temp
; }
688 { int size_temp
= size_a
; size_a
= size_b
; size_b
= size_temp
; }
690 z
= alloclongobject(size_a
+1);
693 for (i
= 0; i
< size_b
; ++i
) {
694 carry
+= a
->ob_digit
[i
] + b
->ob_digit
[i
];
695 z
->ob_digit
[i
] = carry
& MASK
;
696 /* The following assumes unsigned shifts don't
697 propagate the sign bit. */
700 for (; i
< size_a
; ++i
) {
701 carry
+= a
->ob_digit
[i
];
702 z
->ob_digit
[i
] = carry
& MASK
;
705 z
->ob_digit
[i
] = carry
;
706 return long_normalize(z
);
709 /* Subtract the absolute values of two integers. */
711 static longobject
*x_sub
PROTO((longobject
*, longobject
*));
716 int size_a
= ABS(a
->ob_size
), size_b
= ABS(b
->ob_size
);
722 /* Ensure a is the larger of the two: */
723 if (size_a
< size_b
) {
725 { longobject
*temp
= a
; a
= b
; b
= temp
; }
726 { int size_temp
= size_a
; size_a
= size_b
; size_b
= size_temp
; }
728 else if (size_a
== size_b
) {
729 /* Find highest digit where a and b differ: */
731 while (--i
>= 0 && a
->ob_digit
[i
] == b
->ob_digit
[i
])
734 return alloclongobject(0);
735 if (a
->ob_digit
[i
] < b
->ob_digit
[i
]) {
737 { longobject
*temp
= a
; a
= b
; b
= temp
; }
739 size_a
= size_b
= i
+1;
741 z
= alloclongobject(size_a
);
744 for (i
= 0; i
< size_b
; ++i
) {
745 /* The following assumes unsigned arithmetic
746 works module 2**N for some N>SHIFT. */
747 borrow
= a
->ob_digit
[i
] - b
->ob_digit
[i
] - borrow
;
748 z
->ob_digit
[i
] = borrow
& MASK
;
750 borrow
&= 1; /* Keep only one sign bit */
752 for (; i
< size_a
; ++i
) {
753 borrow
= a
->ob_digit
[i
] - borrow
;
754 z
->ob_digit
[i
] = borrow
& MASK
;
759 z
->ob_size
= -(z
->ob_size
);
760 return long_normalize(z
);
770 if (a
->ob_size
< 0) {
771 if (b
->ob_size
< 0) {
773 if (z
!= NULL
&& z
->ob_size
!= 0)
774 z
->ob_size
= -(z
->ob_size
);
795 if (a
->ob_size
< 0) {
800 if (z
!= NULL
&& z
->ob_size
!= 0)
801 z
->ob_size
= -(z
->ob_size
);
822 size_a
= ABS(a
->ob_size
);
823 size_b
= ABS(b
->ob_size
);
824 z
= alloclongobject(size_a
+ size_b
);
827 for (i
= 0; i
< z
->ob_size
; ++i
)
829 for (i
= 0; i
< size_a
; ++i
) {
831 twodigits f
= a
->ob_digit
[i
];
838 for (j
= 0; j
< size_b
; ++j
) {
839 carry
+= z
->ob_digit
[i
+j
] + b
->ob_digit
[j
] * f
;
840 z
->ob_digit
[i
+j
] = carry
& MASK
;
843 for (; carry
!= 0; ++j
) {
844 assert(i
+j
< z
->ob_size
);
845 carry
+= z
->ob_digit
[i
+j
];
846 z
->ob_digit
[i
+j
] = carry
& MASK
;
851 z
->ob_size
= -(z
->ob_size
);
853 z
->ob_size
= -(z
->ob_size
);
854 return (object
*) long_normalize(z
);
857 /* The / and % operators are now defined in terms of divmod().
858 The expression a mod b has the value a - b*floor(a/b).
859 The long_divrem function gives the remainder after division of
860 |a| by |b|, with the sign of a. This is also expressed
861 as a - b*trunc(a/b), if trunc truncates towards zero.
868 So, to get from rem to mod, we have to add b if a and b
869 have different signs. We then subtract one from the 'div'
870 part of the outcome to keep the invariant intact. */
872 static int l_divmod
PROTO((longobject
*, longobject
*,
873 longobject
**, longobject
**));
875 l_divmod(v
, w
, pdiv
, pmod
)
881 longobject
*div
, *mod
;
883 if (long_divrem(v
, w
, &div
, &mod
) < 0)
885 if (mod
->ob_size
< 0 && w
->ob_size
> 0 ||
886 mod
->ob_size
> 0 && w
->ob_size
< 0) {
889 temp
= (longobject
*) long_add(mod
, w
);
896 one
= (longobject
*) newlongobject(1L);
898 (temp
= (longobject
*) long_sub(div
, one
)) == NULL
) {
918 longobject
*div
, *mod
;
919 if (l_divmod(v
, w
, &div
, &mod
) < 0)
922 return (object
*)div
;
930 longobject
*div
, *mod
;
931 if (l_divmod(v
, w
, &div
, &mod
) < 0)
934 return (object
*)mod
;
943 longobject
*div
, *mod
;
944 if (l_divmod(v
, w
, &div
, &mod
) < 0)
946 z
= newtupleobject(2);
948 settupleitem(z
, 0, (object
*) div
);
949 settupleitem(z
, 1, (object
*) mod
);
964 longobject
*z
, *div
, *mod
;
969 err_setstr(ValueError
, "long integer to the negative power");
972 z
= (longobject
*)newlongobject(1L);
974 for (i
= 0; i
< size_b
; ++i
) {
975 digit bi
= b
->ob_digit
[i
];
978 for (j
= 0; j
< SHIFT
; ++j
) {
982 temp
= (longobject
*)long_mul(z
, a
);
984 if ((object
*)c
!=None
&& temp
!=NULL
) {
985 l_divmod(temp
, c
, &div
, &mod
);
995 if (bi
== 0 && i
+1 == size_b
)
997 temp
= (longobject
*)long_mul(a
, a
);
999 if ((object
*)c
!=None
&& temp
!=NULL
) {
1000 l_divmod(temp
, c
, &div
, &mod
);
1012 if (a
== NULL
|| z
== NULL
)
1016 if ((object
*)c
!=None
&& z
!=NULL
) {
1017 l_divmod(z
, c
, &div
, &mod
);
1029 /* Implement ~x as -(x+1) */
1032 w
= (longobject
*)newlongobject(1L);
1035 x
= (longobject
*) long_add(v
, w
);
1039 if (x
->ob_size
!= 0)
1040 x
->ob_size
= -(x
->ob_size
);
1058 n
= ABS(v
->ob_size
);
1062 return (object
*) v
;
1064 z
= alloclongobject(ABS(n
));
1067 for (i
= 0; i
< n
; i
++)
1068 z
->ob_digit
[i
] = v
->ob_digit
[i
];
1069 z
->ob_size
= -(v
->ob_size
);
1089 return ABS(v
->ob_size
) != 0;
1099 int newsize
, wordshift
, loshift
, hishift
, i
, j
;
1100 digit lomask
, himask
;
1102 if (a
->ob_size
< 0) {
1103 /* Right shifting negative numbers is harder */
1104 longobject
*a1
, *a2
, *a3
;
1105 a1
= (longobject
*) long_invert(a
);
1106 if (a1
== NULL
) return NULL
;
1107 a2
= (longobject
*) long_rshift(a1
, b
);
1109 if (a2
== NULL
) return NULL
;
1110 a3
= (longobject
*) long_invert(a2
);
1112 return (object
*) a3
;
1115 shiftby
= getlongvalue((object
*)b
);
1116 if (shiftby
== -1L && err_occurred())
1119 err_setstr(ValueError
, "negative shift count");
1122 wordshift
= shiftby
/ SHIFT
;
1123 newsize
= ABS(a
->ob_size
) - wordshift
;
1125 z
= alloclongobject(0);
1128 loshift
= shiftby
% SHIFT
;
1129 hishift
= SHIFT
- loshift
;
1130 lomask
= ((digit
)1 << hishift
) - 1;
1131 himask
= MASK
^ lomask
;
1132 z
= alloclongobject(newsize
);
1136 z
->ob_size
= -(z
->ob_size
);
1137 for (i
= 0, j
= wordshift
; i
< newsize
; i
++, j
++) {
1138 z
->ob_digit
[i
] = (a
->ob_digit
[j
] >> loshift
) & lomask
;
1141 (a
->ob_digit
[j
+1] << hishift
) & himask
;
1143 return (object
*) long_normalize(z
);
1153 int newsize
, wordshift
, loshift
, hishift
, i
, j
;
1154 digit lomask
, himask
;
1156 shiftby
= getlongvalue((object
*)b
);
1157 if (shiftby
== -1L && err_occurred())
1160 err_setstr(ValueError
, "negative shift count");
1163 if (shiftby
> MASK
) {
1164 err_setstr(ValueError
, "outrageous left shift count");
1167 if (shiftby
% SHIFT
== 0) {
1168 wordshift
= shiftby
/ SHIFT
;
1171 newsize
= ABS(a
->ob_size
) + wordshift
;
1176 wordshift
= shiftby
/ SHIFT
+ 1;
1177 loshift
= SHIFT
- shiftby
%SHIFT
;
1178 hishift
= shiftby
% SHIFT
;
1179 newsize
= ABS(a
->ob_size
) + wordshift
;
1180 lomask
= ((digit
)1 << hishift
) - 1;
1181 himask
= MASK
^ lomask
;
1183 z
= alloclongobject(newsize
);
1187 z
->ob_size
= -(z
->ob_size
);
1188 for (i
= 0; i
< wordshift
; i
++)
1190 for (i
= wordshift
, j
= 0; i
< newsize
; i
++, j
++) {
1193 (a
->ob_digit
[j
] << hishift
) & himask
;
1195 (a
->ob_digit
[j
] >> loshift
) & lomask
;
1197 return (object
*) long_normalize(z
);
1201 /* Bitwise and/xor/or operations */
1203 #define MAX(x, y) ((x) < (y) ? (y) : (x))
1204 #define MIN(x, y) ((x) > (y) ? (y) : (x))
1206 static object
*long_bitwise
PROTO((longobject
*, int, longobject
*));
1208 long_bitwise(a
, op
, b
)
1210 int op
; /* '&', '|', '^' */
1213 digit maska
, maskb
; /* 0 or MASK */
1215 int size_a
, size_b
, size_z
;
1221 if (a
->ob_size
< 0) {
1222 a
= (longobject
*) long_invert(a
);
1229 if (b
->ob_size
< 0) {
1230 b
= (longobject
*) long_invert(b
);
1238 size_a
= a
->ob_size
;
1239 size_b
= b
->ob_size
;
1240 size_z
= MAX(size_a
, size_b
);
1241 z
= alloclongobject(size_z
);
1242 if (a
== NULL
|| b
== NULL
|| z
== NULL
) {
1252 if (maska
!= maskb
) {
1258 if (maska
&& maskb
) {
1266 if (maska
|| maskb
) {
1275 for (i
= 0; i
< size_z
; ++i
) {
1276 diga
= (i
< size_a
? a
->ob_digit
[i
] : 0) ^ maska
;
1277 digb
= (i
< size_b
? b
->ob_digit
[i
] : 0) ^ maskb
;
1279 case '&': z
->ob_digit
[i
] = diga
& digb
; break;
1280 case '|': z
->ob_digit
[i
] = diga
| digb
; break;
1281 case '^': z
->ob_digit
[i
] = diga
^ digb
; break;
1287 z
= long_normalize(z
);
1289 return (object
*) z
;
1300 return long_bitwise(a
, '&', b
);
1308 return long_bitwise(a
, '^', b
);
1316 return long_bitwise(a
, '|', b
);
1324 if (is_intobject(*pw
)) {
1325 *pw
= newlongobject(getintvalue(*pw
));
1329 return 1; /* Can't do it */
1337 x
= getlongvalue(v
);
1340 return newintobject(x
);
1355 return newfloatobject(dgetlongvalue(v
));
1362 return long_format(v
, 8);
1369 return long_format(v
, 16);
1373 #define UF (unaryfunc)
1374 #define BF (binaryfunc)
1375 #define TF (ternaryfunc)
1376 #define IF (inquiry)
1378 static number_methods long_as_number
= {
1379 BF long_add
, /*nb_add*/
1380 BF long_sub
, /*nb_subtract*/
1381 BF long_mul
, /*nb_multiply*/
1382 BF long_div
, /*nb_divide*/
1383 BF long_mod
, /*nb_remainder*/
1384 BF long_divmod
, /*nb_divmod*/
1385 TF long_pow
, /*nb_power*/
1386 UF long_neg
, /*nb_negative*/
1387 UF long_pos
, /*tp_positive*/
1388 UF long_abs
, /*tp_absolute*/
1389 IF long_nonzero
,/*tp_nonzero*/
1390 UF long_invert
, /*nb_invert*/
1391 BF long_lshift
, /*nb_lshift*/
1392 BF long_rshift
, /*nb_rshift*/
1393 BF long_and
, /*nb_and*/
1394 BF long_xor
, /*nb_xor*/
1395 BF long_or
, /*nb_or*/
1396 (int (*) FPROTO((object
**, object
**)))
1397 (coercion
)long_coerce
, /*nb_coerce*/
1398 UF long_int
, /*nb_int*/
1399 UF long_long
, /*nb_long*/
1400 UF long_float
, /*nb_float*/
1401 UF long_oct
, /*nb_oct*/
1402 UF long_hex
, /*nb_hex*/
1405 typeobject Longtype
= {
1406 OB_HEAD_INIT(&Typetype
)
1409 sizeof(longobject
) - sizeof(digit
),
1411 (destructor
)long_dealloc
, /*tp_dealloc*/
1415 (int (*) FPROTO((object
*, object
*)))
1416 (cmpfunc
)long_compare
, /*tp_compare*/
1417 (reprfunc
)long_repr
, /*tp_repr*/
1418 &long_as_number
,/*tp_as_number*/
1419 0, /*tp_as_sequence*/
1420 0, /*tp_as_mapping*/
1421 (long (*) FPROTO((object
*)))
1422 (hashfunc
)long_hash
, /*tp_hash*/