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