开发者

Writing formatted text in SWI-Prolog

开发者 https://www.devze.com 2023-04-11 01:30 出处:网络
I have spent a significant amount of time in the SWI-Prolog documentation and am getting nowhere.My desire is to be able to format numbers that are output such that I am controlling total # decimal di

I have spent a significant amount of time in the SWI-Prolog documentation and am getting nowhere. My desire is to be able to format numbers that are output such that I am controlling total # decimal digits displayed and also right aligning the numbers in a given character width. For example:

  2.500   (trailing zeroes displayed)
 34.432   (rounded from a much longer decimal value)
213.110

All 3 are right aligned in a 7 character wide space, with 3 decimal places displayed (even when those are zero). I can accomplish some of these things individually, but not all at once.

writef( '%7R', [34.342]).
writef( '%7R'开发者_StackOverflow中文版, [34.300]).

^^^ This comes very close to what I want, but unfortunately it does display any trailing zeroes (it will always omit them). Also, I have to do the rounding manually before passing the rounded value to writef().

format( '~3f', 34.34219089).
format( '~3f', 1234.3).

This one does the rounding, and allows trailing zeroes, but I can find no way to force right alignment using the "format" function, and I can't find a way to combine the functionality of writef (alignment) with format (rounding and zero display).

Any ideas?

Thanks much!


I got the very same problem, and more:

[debug]  ?- format( '~3f', 34.34219089).
34,342

The comma (albeit required by locale, watch out for this) complicates reading back the output. I ended up with some ugly workaround to control rounding:

[debug]  ?- X is round(34.34219089 * 1000) / 1000, write(X).
34.342
X = 34.342.

To pad and align you should use tab stops, controlled by pairs of t and |. Documentation it's a bit too much synthetic on this topic. For instance, to print a table of numbers in spreadsheet default style (text left align, number right align):

test(indent) :- nl,
    forall(member(L, [[a,    3.66,      55.5334],
              [basd, 22.876345, 2113.4465],
              [cas,  0.6623233, 53.5]
             ]),
           format('~s~t~20|~t~3f~40|~t~3f~60|~n', L)).

Note the position of 'space allocator' specifier ~t, the absolute 'column width' ~|, regards the field type specifier. The output:

?- run_tests(sheet_inventory:indent).
% PL-Unit: sheet_inventory:indent 
a                                  3,660              55,533
basd                              22,876            2113,447
cas                                0,662              53,500
0

精彩评论

暂无评论...
验证码 换一张
取 消