Using sprintf to match the results of format

16 Ansichten (letzte 30 Tage)
John D'Errico
John D'Errico am 20 Jul. 2017
Kommentiert: Captain Karnage am 14 Jun. 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.

Antworten (3)

Steven Lord
Steven Lord am 20 Jul. 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 Kommentar
Ulises Nunez Garzon
Ulises Nunez Garzon am 27 Okt. 2021
Bearbeitet: Ulises Nunez Garzon am 27 Okt. 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

Melden Sie sich an, um zu kommentieren.


dpb
dpb am 20 Jul. 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 Kommentare
dpb
dpb am 20 Jul. 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 am 20 Jul. 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.

Melden Sie sich an, um zu kommentieren.


Stephen23
Stephen23 am 27 Okt. 2021
format short
str = strtrim(formattedDisplayText(pi))
str = "3.1416"
format long E
str = strtrim(formattedDisplayText(pi))
str = "3.141592653589793e+00"
  1 Kommentar
Captain Karnage
Captain Karnage am 14 Jun. 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"

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Characters and Strings finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by