Using sprintf to match the results of format

7 visualizaciones (últimos 30 días)
John D'Errico
John D'Errico el 20 de Jul. de 2017
Comentada: Captain Karnage el 14 de Jun. de 2023
If I read the help for format, it tells me:
format may be used to switch between different output display formats
of all float variables as follows:
format SHORT Scaled fixed point format with 5 digits.
format LONG Scaled fixed point format with 15 digits for double
and 7 digits for single.
format SHORTE Floating point format with 5 digits.
format LONGE Floating point format with 15 digits for double and
7 digits for single.
format SHORTG Best of fixed or floating point format with 5
digits.
format LONGG Best of fixed or floating point format with 15
digits for double and 7 digits for single.
format SHORTENG Engineering format that has at least 5 digits
and a power that is a multiple of three
format LONGENG Engineering format that has exactly 16 significant
digits and a power that is a multiple of three.
I'd like to replicate the behavior of each of these formats, using an appropriate format spec in sprintf. The purpose is for a custom numeric class I was thinking of writing. I'd happily ignore longeng and shorteng, if they were problematic. While I can probably play around with format specs and get something reasonable, someone else is surely much more knowledgable in this matter than me.

Respuestas (3)

Steven Lord
Steven Lord el 20 de Jul. de 2017
The easiest way to replicate the format specification is to just let MATLAB do it.
oldFormat = get(0, 'Format');
% may want to set up an onCleanup object here to restore the format
% to guard against one of the next few commands throwing an error
% But for demonstration purposes, I assume everything will work fine
% 'replicate' the short format
format short
dataToDisplay = pi;
s = evalc('disp(dataToDisplay)');
% Everything worked fine up to this point, so reset the format
format(oldFormat)
If you're displaying an array, you may also want to get(0, 'FormatSpacing') so you can handle 'loose' and 'compact'.
There are some tools in MATLAB for customizing object display, though I believe those are targeted for helping display groups of properties of an object.
  1 comentario
Ulises Nunez Garzon
Ulises Nunez Garzon el 27 de Oct. de 2021
Editada: Ulises Nunez Garzon el 27 de Oct. de 2021
This is a great answer. To top it off, I would wrap your code to get the desired result in the following way:
function c_str = c_format_short(a)
oldFormat = get(0, 'Format');
dataToDisplay = a;
c_str = evalc('disp(dataToDisplay)');
c_str = strtrim(c_str(2:end-1));
format(oldFormat)
end

Iniciar sesión para comentar.


dpb
dpb el 20 de Jul. de 2017
As a starting point
>> fnprnt=@(x) fprintf('%.5g\n',x)
fnprnt =
@(x)fprintf('%.5g\n',x)
>> fnprnt(pi)
3.1416
>> fnprnt(pi*1E6)
3.1416e+06
>> format short
>> pi
ans =
3.1416
>> pi*1E6
ans =
3.1416e+06
>>
  3 comentarios
dpb
dpb el 20 de Jul. de 2017
Yeah, I don't think there's any single format string that reproduces any of the FORMAT choices exactly excepting perhaps for 'bank' as a '|.2f'|. But I'm not certain there on the rounding...does Matlab use "bankers' rounding"? Don't think it's documented.
Walter Roberson
Walter Roberson el 20 de Jul. de 2017
There is no one format that can replicate the format short output. %13.5g helps (the 13 part deals with the spacing), but format short treats integral values differently than non-integral value, always displaying 0 after the decimal point for non-integral values that %g would not display. 1+eps for example is displayed as 1.0000 but 1 exactly is displayed with no decimal places. %g would display 1+eps with no trailing 0, and the %e and %f formats would always display trailing 0 even for integral values.

Iniciar sesión para comentar.


Stephen23
Stephen23 el 27 de Oct. de 2021
format short
str = strtrim(formattedDisplayText(pi))
str = "3.1416"
format long E
str = strtrim(formattedDisplayText(pi))
str = "3.141592653589793e+00"
  1 comentario
Captain Karnage
Captain Karnage el 14 de Jun. de 2023
This is a welcome addition. However, in your example, you're still setting the system format first, then calling formattedDisplayText. The beauty of formattedDisplayText is you can, as a parameter, specify the exact format you want using the 'NumericFormat' name/value pair without calling the format function e.g.
strtrim( formattedDisplayText( pi, 'NumericFormat', 'longEng' ) )
ans = "3.14159265358979e+000"

Iniciar sesión para comentar.

Categorías

Más información sobre Characters and Strings en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by