diff: bug fix for handling of MININT

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Mar 13 11:00:20 AEDT 1998


Tom has already done an over-the-shoulder review of this one.

library/string.m:
	Fix a bug in string__base_string_to_int:
	it was handling MININT incorrectly.

tests/hard_coded/Mmakefile:
tests/hard_coded/minint_bug.m:
tests/hard_coded/minint_bug.exp:
	Regression test.

cvs diff -N library/string.m tests/hard_coded/Mmakefile tests/hard_coded/minint_bug.exp tests/hard_coded/minint_bug.m
Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.101
diff -u -r1.101 string.m
--- string.m	1998/01/30 02:15:05	1.101
+++ string.m	1998/03/12 23:44:31
@@ -516,31 +516,36 @@
 :- mode string__int_to_base_string_1(in, in, out) is det.
 
 string__int_to_base_string_1(N, Base, Str) :-
+	% Note that in order to handle MININT correctly,
+	% we need to do the conversion of the absolute
+	% number into digits using negative numbers
+	% (we can't use positive numbers, since -MININT overflows)
 	(
 		N < 0
 	->
-		N1 is 0 - N,
-		string__int_to_base_string_2(N1, Base, Str1),
+		string__int_to_base_string_2(N, Base, Str1),
 		string__append("-", Str1, Str)
 	;
-		string__int_to_base_string_2(N, Base, Str)
+		N1 is 0 - N,
+		string__int_to_base_string_2(N1, Base, Str)
 	).
 
 :- pred string__int_to_base_string_2(int, int, string).
 :- mode string__int_to_base_string_2(in, in, out) is det.
 
-string__int_to_base_string_2(N, Base, Str) :-
+string__int_to_base_string_2(NegN, Base, Str) :-
 	(
-		N < Base
+		NegN > -Base
 	->
+		N is -NegN,
 		char__det_int_to_digit(N, DigitChar),
 		string__char_to_string(DigitChar, Str)
 	;
-		N10 is N mod Base,
-		N1 is N // Base,
+		NegN1 is NegN // Base,
+		N10 is (NegN1 * Base) - NegN,
 		char__det_int_to_digit(N10, DigitChar),
 		string__char_to_string(DigitChar, DigitString),
-		string__int_to_base_string_2(N1, Base, Str1),
+		string__int_to_base_string_2(NegN1, Base, Str1),
 		string__append(Str1, DigitString, Str)
 	).
 
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.21
diff -u -r1.21 Mmakefile
--- Mmakefile	1998/03/11 19:36:26	1.21
+++ Mmakefile	1998/03/12 23:49:59
@@ -44,6 +44,7 @@
 	ho_solns \
 	ho_univ_to_type \
 	impossible_unify \
+	minint_bug \
 	mode_choice \
 	name_mangling \
 	no_fully_strict \
Index: tests/hard_coded/minint_bug.exp
===================================================================
RCS file: minint_bug.exp
diff -N minint_bug.exp
--- /dev/null	Fri Mar 13 10:36:06 1998
+++ minint_bug.exp	Fri Mar 13 10:57:20 1998
@@ -0,0 +1,3 @@
+-2147483648
+-2147483648
+-2147483648
Index: tests/hard_coded/minint_bug.m
===================================================================
RCS file: minint_bug.m
diff -N minint_bug.m
--- /dev/null	Fri Mar 13 10:36:06 1998
+++ minint_bug.m	Fri Mar 13 10:56:37 1998
@@ -0,0 +1,26 @@
+% regression test: versions 0.7.3 and earlier failed this test.
+
+:- module minint_bug.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module int, list, string.
+
+main -->
+	{ string__int_to_string(-2147483648, S) }, print(S), nl,
+	print(-2147483648), nl,
+	format("%d\n", [i(-2147483648)]).
+/*
+We could test the following too, but the correct output is machine-dependent,
+which makes it difficult to validate the results of the test.
+	{ int__min_int(MinInt) },
+	{ string__int_to_string(MinInt, S2) }, print(S2), nl,
+	print(MinInt), nl,
+	format("%d\n", [i(MinInt)]), nl.
+*/

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list