[m-rev.] for review: mercury implementation of float_to_string

Peter Ross pro at missioncriticalit.com
Sat Nov 23 02:20:58 AEDT 2002


Hi,

For stayl to review.

===================================================================


Estimated hours taken: 2
Branches: main

Provide a mercury implementation of string__float_to_string.  This is
needed so that string__float_to_string returns the same output on all
backends.

library/string.m:
	Implementation of string__float_to_string in Mercury by using
	string__format.

Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.186
diff -u -r1.186 string.m
--- library/string.m	21 Nov 2002 09:21:33 -0000	1.186
+++ library/string.m	22 Nov 2002 15:16:19 -0000
@@ -1829,13 +1829,60 @@
 :- pragma foreign_proc("C",
 	string__float_to_string(Flt::in, Str::uo),
 		[will_not_call_mercury, promise_pure, thread_safe], "{
+	/*
+	** For efficiency reasons we duplicate the C implementation
+	** of string__lowlevel_float_to_string
+	*/
+	char buf[ML_SPRINTF_FLOAT_BUF_SIZE];
+	ML_sprintf_float(buf, Flt);
+	MR_make_aligned_string_copy(Str, buf);
+}").
+
+	% XXX The unsafe_promise_unique is needed because in
+	% string__float_to_string_2 the call to string__to_float doesn't
+	% have a (ui, out) mode hence the output string cannot be unique.
+string__float_to_string(Float, unsafe_promise_unique(String)) :-
+	String = string__float_to_string_2(min_precision, Float).
+
+:- func string__float_to_string_2(int, float) = (string) is det.
+
+string__float_to_string_2(Prec, Float) = String :-
+	string__format("%#." ++ int_to_string(Prec) ++ "g", [f(Float)], Tmp),
+	( Prec = max_precision ->
+		String = Tmp
+	;
+		( string__to_float(Tmp, Float) ->
+			String = Tmp
+		;
+			String = float_to_string_2(Prec + 1, Float)
+		)
+	).
+
+	% We assume that on non-C backends that we are using double
+	% precision floats.
+:- func min_precision = int.
+min_precision = 15.
+
+:- func max_precision = int.
+max_precision = 17.
+
+:- pred string__lowlevel_float_to_string(float, string).
+:- mode string__lowlevel_float_to_string(in, uo) is det.
+
+:- pragma foreign_proc("C",
+	string__lowlevel_float_to_string(Flt::in, Str::uo),
+		[will_not_call_mercury, promise_pure, thread_safe], "{
+	/*
+	** Note anychanges here will require the same changes in
+	** string__float_to_string.
+	*/
 	char buf[ML_SPRINTF_FLOAT_BUF_SIZE];
 	ML_sprintf_float(buf, Flt);
 	MR_make_aligned_string_copy(Str, buf);
 }").
 
 :- pragma foreign_proc("C#",
-	string__float_to_string(FloatVal::in, FloatString::uo),
+	string__lowlevel_float_to_string(FloatVal::in, FloatString::uo),
 	[will_not_call_mercury, promise_pure, thread_safe], "
 
 		// The R format string prints the double out such that it
@@ -1846,10 +1893,10 @@
 	FloatString = FloatVal.ToString(""R"");
 ").
 
-string__float_to_string(_, _) :-
+string__lowlevel_float_to_string(_, _) :-
 	% This version is only used for back-ends for which there is no
 	% matching foreign_proc version.
-	private_builtin__sorry("string__float_to_string").
+	private_builtin__sorry("string__lowlevel_float_to_string").
 
 :- pragma foreign_decl(c, "
 #ifdef MR_USE_SINGLE_PREC_FLOAT

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list