# for review: big ints again

Bert Thompson aet at hydra.cs.mu.oz.au
Thu Apr 9 18:47:19 AEST 1998

```Fergus Henderson <fjh at cs.mu.OZ.AU> writes:

| > :- func int_to_integer(int) = integer.
| > int_to_integer(D) = i(signum(D), pos_int_to_digits(AD)) :-
| > 	int__abs(D, AD).

|This function does the wrong thing for MININT.
|(See, isn't code review wonderful? ;-)

Well spotted. 8^)

Here's the new diff.

------------------------------------------------------------
*** 1.27	1998/04/09 05:47:39
--- 1.28	1998/04/09 08:40:31
***************
*** 97,104 ****

:- func integer:'*'(integer, integer) = integer.

- :- func integer:'/'(integer, integer) = integer.
-
:- func integer:'//'(integer, integer) = integer.

:- func integer:'div'(integer, integer) = integer.
--- 97,102 ----
***************
*** 180,188 ****
integer:'div'(X1, X2) =
big_div(X1, X2).

- integer:'/'(X1, X2) =
- 	big_quot(X1, X2).
-
integer:'//'(X1, X2) =
big_quot(X1, X2).

--- 178,183 ----
***************
*** 351,363 ****
integer(N) =
int_to_integer(N).

:- func int_to_integer(int) = integer.
! int_to_integer(D) = i(signum(D), pos_int_to_digits(AD)) :-
! 	int__abs(D, AD).

:- func signum(int) = int.
signum(N) = SN :-
! 	(N < 0 ->
SN = -1
; N = 0 ->
SN = 0
--- 346,372 ----
integer(N) =
int_to_integer(N).

+ 	% Note: Since most machines use 2's complement arithmetic,
+ 	% INT_MIN is usually -INT_MAX-1, hence -INT_MIN will
+ 	% cause int overflow. We handle overflow below.
:- func int_to_integer(int) = integer.
! int_to_integer(D) = Int :-
! 	int__abs(D, AD),
! 	( (AD < 0 ; AD=0, D \= 0) ->
! 		% int overflow occurred.
! 		D2 = D + int_max,
! 		Int = integer(D2) - integer(int_max)
! 	;
! 		Int = i(signum(D), pos_int_to_digits(AD))
! 	).
!
! :- func int_max = int.
! int_max = Maxint :-
! 	int:max_int(Maxint).

:- func signum(int) = int.
signum(N) = SN :-
! 	( N < 0 ->
SN = -1
; N = 0 ->
SN = 0
***************
*** 684,690 ****
list__reverse(Xs, RXs),
list__reverse(Ys, RYs),
C = big_cmp(i(1, RXs), i(1, RYs)),
! 	( C = greaterthan ; C = equal).

:- pred pos_is_zero(list(digit)).
:- mode pos_is_zero(in) is semidet.
--- 693,699 ----
list__reverse(Xs, RXs),
list__reverse(Ys, RYs),
C = big_cmp(i(1, RXs), i(1, RYs)),
! 	( C = greaterthan ; C = equal ).

:- pred pos_is_zero(list(digit)).
:- mode pos_is_zero(in) is semidet.
***************
*** 692,698 ****
nuke_zeros(Ds) = [].

integer:pow(A, N, P) :-
! 	( N < integer(0) ->
error("integer:pow: negative exponent")
;
P = big_pow(A, N)
--- 701,707 ----
nuke_zeros(Ds) = [].

integer:pow(A, N, P) :-
! 	( N < zero ->
error("integer:pow: negative exponent")
;
P = big_pow(A, N)
***************
*** 700,712 ****

:- func big_pow(integer, integer) = integer.
big_pow(A, N) = P :-
! 	( N = integer(0) ->
! 		P = integer(1)
; big_odd(N) ->
! 		P = A * big_pow(A, N-integer(1))
; % even
! 		P = big_sqr(big_pow(A, N/integer(2)))
).

:- func big_sqr(integer) = integer.
big_sqr(A) = A * A.
--- 709,724 ----

:- func big_pow(integer, integer) = integer.
big_pow(A, N) = P :-
! 	( N = zero ->
! 		P = one
; big_odd(N) ->
! 		P = A * big_pow(A, N-one)
; % even
! 		P = big_sqr(big_pow(A, N//two))
).
+
+ :- func two = integer.
+ two = integer(2).

:- func big_sqr(integer) = integer.
big_sqr(A) = A * A.
***************
*** 714,723 ****
:- pred big_odd(integer).
:- mode big_odd(in) is semidet.
big_odd(N) :-
! 	( N = integer(0) ->
! 		fail
! 	;
! 		N = i(_S, [D|_Ds]),
! 		D mod 2 = 1
! 	).

--- 726,731 ----
:- pred big_odd(integer).
:- mode big_odd(in) is semidet.
big_odd(N) :-
! 	N = i(_S, [D|_Ds]),
! 	D mod 2 = 1.

```

More information about the developers mailing list