In the docs I often see things like %6.4f, %.16lg, %.12g, etc. I know that it is to control the decimals of numbers, but I don’t understand what does it means. I usually do try and error until I get the decimals that I want. Where I can read about that syntax? Is that C language printf? Could you share any good link/tutorial? Thanks in advance.
Yes, this is like C’s
printf (or bash’s
printf as the examples below). You could check out https://linux.die.net/man/3/printf. I’ve also struggled with this. I made a cheat sheet for myself, maybe it is of use.
For your specific case, controlling decimals, it’s like this:
%[width].[no of decimals][type]
$ printf "%g \n" "3.14159265358979323" 3.14159 printf "%10.3g \n" "3.14159265358979323" 3.14 $ printf "%10.8g \n" "3.14159265358979323" 3.1415927 $ printf "%.16g \n" "3.14159265358979323" 3.141592653589793
I’m confused though; why does
printf "%10.3g \n" "3.14159265358979323" print two decimals and not three? Maybe some divine C programmer can answer. EDIT: changing the type from g to f gives the expected result.
| printf | %[-][n][.][n][h,l]cc | |-----------|------------------------------------------------------| | % | conversion specification | | - | specifies left adjustment | | n | specifies the minimum field width | | . | separates the field width from the precision | | n | max number of chars (string) | | | OR number of digits after decimal point (float) | | | OR min. number of digits (int) | | h | print int as short | | l | (letter ell) print int as long | | cc | conversion character | | | | | Character | Argument type; Printed As | | d,i | int (decimal number) | | o | int; unsigned octal number | | x,X | int; unsigned hexadecimal number | | u | int; unsigned decimal number | | c | int; single character | | s | char *; (tekststreng) | | f | double; [-] m.dddddd , d = precision (6). | | e,E | double; [-] m.dddddd e+/- xx or [-] m.dddddd E+/- xx | | g,G | double; use %e or %E if the exponent is less than -4 | | p | void *; pointer | | % | no argument is converted; print a % |
See the Matlab manual for fprintf
%g specifier is tricky (but often the most usefull one) and many manuals about it are wrong. See this SO question/answer. The best thing on
%g is that it removes trailing zeros.
julia> @printf("%.15g", 0.3333) 0.3333 julia> @printf("%.15f", 0.3333) 0.333300000000000
Maybe it would be a nice addition to the man-pages to include a small paragraph on how to specify these
printf templates. They are mentioned two times in https://docs.generic-mapping-tools.org/6.1/gmt.conf.html#format-parameters:
FORMAT_FLOAT_MAP Format (C language printf syntax) to be used when plotting double precision floating point numbers along plot frames and contours. For geographic coordinates, see [FORMAT_GEO_MAP](https://docs.generic-mapping-tools.org/6.1/gmt.conf.html#term-FORMAT_GEO_MAP). [%.12lg]. FORMAT_FLOAT_OUT Format (C language printf syntax) to be used when printing double precision floating point numbers to output files. For geographic coordinates, see [FORMAT_GEO_OUT](https://docs.generic-mapping-tools.org/6.1/gmt.conf.html#term-FORMAT_GEO_OUT). [%.12lg]. To give some columns a separate format, supply one or more comma-separated *cols*:*format* specifications, where *cols* can be specific columns (e.g., 5 for 6th since 0 is the first) or a range of columns (e.g., 3-7). The last specification without column information will override the format for all other columns. Alternatively, you can list N space-separated formats and these apply to the first N columns.
Yes, that would be a nice addition. Would you mind making a pull request. Add it to FORMAT_FLOAT_OUT and just refer to FORMAT_FLOAT_OUT from FORMAT_FLOAT_MAP.
I thought the whole point of using
printf-type of output was that you always know what you get. With
%g, this does not seem to be the case; what you get (length and precision) depends of the input number.
I read through the SO post you shared. I feel a bit wiser, but still not quite ‘arrived’. Based on purely empirical example:
$ printf "%.5g\n" "2.33335234" 2.3334 $ printf "%.5f\n" "2.33335234" 2.33335
Explanation based on my primitive, outdated neural network:
%.ng- round off the the number based on the nth-precision number and give (n-1) decimals.
%.nf- print n decimals - what I specified
What is the rationale of choosing
%f as default? Remove traliing zeros, as Joaquim mentioned? And why include
l (as in
%.12lg)? Based on my interpretation this causes int to be printed as long, but we’re not dealing with int’s here, no? From https://en.wikipedia.org/wiki/Printf_format_string:
For floating point types, this [l] is ignored. float arguments are always promoted to double when used in a varargs call.
Again, sorry, no
>> fprintf('%.5g\n', 10.3333333) 10.333 >> fprintf('%.3g\n', 1/30) 0.0333 >> fprintf('%.5g\n', 10.3333333) 10.333 >> fprintf('%.3g\n', 1/30) 0.0333 >> fprintf('%.4g\n', 12.001) 12 >> fprintf('%.5g\n', 12.001) 12.001
Note that the Matlab page says
%g prints the significant digits not the number of decimal digits. Except that it doesn’t print the trailing zeros, even when they are significant (the two 0s in
%g specially when I want to convert numbers into strings (for example when building -R option). Otherwise use what you feel it’s better for your case.
Thanks Joaquim, for enlightening me.