forked from mthom/scryer-prolog
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FIXED: formatting of floats in library(format)
This addresses mthom#2771, using a new internal predicate resorting to to_string(). Many thanks to Trevor Merrifield for reporting this issue! There is still room for improvements: With better support for inspecting floats, more of this logic can be moved to Prolog; also, there may be a way to obtain the float with greater precision, and with fewer needed Rust primitives.
- Loading branch information
Showing
4 changed files
with
65 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
Written 2020-2024 by Markus Triska ([email protected]) | ||
Written 2020-2025 by Markus Triska ([email protected]) | ||
Part of Scryer Prolog. | ||
I place this code in the public domain. Use it in any way you want. | ||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | ||
|
@@ -284,36 +284,12 @@ | |
cells(Fs, Args, 0, [], VNs). | ||
cells([~,s|Fs], [Arg|Args], Tab, Es, VNs) --> !, | ||
cells(Fs, Args, Tab, [chars(Arg)|Es], VNs). | ||
cells([~,f|Fs], [Arg|Args], Tab, Es, VNs) --> !, | ||
{ G = format_number_chars(Arg, Chars) }, | ||
cells(Fs, Args, Tab, [chars(Chars),goal(G)|Es], VNs). | ||
cells([~,f|Fs], Args, Tab, Es, VNs) --> !, | ||
cells([~,'6',f|Fs], Args, Tab, Es, VNs). | ||
cells([~|Fs0], Args0, Tab, Es, VNs) --> | ||
{ numeric_argument(Fs0, Num, [f|Fs], Args0, [Arg|Args]) }, | ||
!, | ||
{ G = (format_number_chars(Arg, Cs0), | ||
phrase(upto_what(Bs, .), Cs0, Cs), | ||
( Num =:= 0 -> Chars = Bs | ||
; ( Cs = ['.'|Rest] -> | ||
length(Rest, L), | ||
( Num < L -> | ||
length(Ds, Num), | ||
append(Ds, _, Rest) | ||
; Num =:= L -> | ||
Ds = Rest | ||
; Num > L, | ||
Delta is Num - L, | ||
% we should look into the float with | ||
% greater accuracy here, and use the | ||
% actual digits instead of 0. | ||
length(Zs, Delta), | ||
maplist(=('0'), Zs), | ||
append(Rest, Zs, Ds) | ||
) | ||
; length(Ds, Num), | ||
maplist(=('0'), Ds) | ||
), | ||
append(Bs, ['.'|Ds], Chars) | ||
)) }, | ||
{ G = float_digits_chars(Arg, Num, Chars) }, | ||
cells(Fs, Args, Tab, [chars(Chars),goal(G)|Es], VNs). | ||
cells([~,r|Fs], Args, Tab, Es, VNs) --> !, | ||
cells([~,'8',r|Fs], Args, Tab, Es, VNs). | ||
|
@@ -368,9 +344,30 @@ | |
Fs1 = [_|_] }, | ||
cells(Fs, Args, Tab, [chars(Fs1)|Es], VNs). | ||
|
||
format_number_chars(N0, Chars) :- | ||
N is N0, % evaluate compound expression | ||
number_chars(N, Chars). | ||
|
||
float_digits_chars(F0, Num, Chars) :- | ||
F is float(F0), % evaluate compound expression and convert to float | ||
'$float_to_chars'(F, Cs0), | ||
phrase(upto_what(Bs, .), Cs0, Cs), | ||
( Num =:= 0 -> Chars = Bs | ||
; ( Cs = ['.'|Rest] -> | ||
length(Rest, L), | ||
( Num < L -> | ||
length(Ds, Num), | ||
append(Ds, _, Rest) | ||
; Num =:= L -> | ||
Ds = Rest | ||
; Num > L, | ||
Delta is Num - L, | ||
length(Zs, Delta), | ||
maplist(=('0'), Zs), | ||
append(Rest, Zs, Ds) | ||
) | ||
; length(Ds, Num), | ||
maplist(=('0'), Ds) | ||
), | ||
append(Bs, ['.'|Ds], Chars) | ||
). | ||
|
||
n_newlines(N0) --> { N0 > 0, N is N0 - 1 }, [newline], n_newlines(N). | ||
n_newlines(0) --> []. | ||
|
@@ -564,6 +561,15 @@ | |
?- format("~12r", [300]). | ||
210 true. | ||
?- format("~f", [3]). | ||
3.000000 true. | ||
?- format("~6f", [1.0e20]). | ||
100000000000000000000.000000 true. | ||
?- format("~50f", [3.0e-20]). | ||
0.00000000000000000003000000000000000000000000000000 true. | ||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | ||
|
||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters