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