Format number in the same format as disp

I want to format number to the string with the same format as used by disp to output numbers. So I want to write function my_format that would take number and output same string as disp. I don't need new lines, just correctly formatted number. For example
>> format
>> pi
ans =
3.1416
>> my_format(pi)
ans =
'3.1416'
>> format long
>> pi
ans =
3.141592653589793
>> my_format(pi)
ans =
'3.141592653589793'

7 Comments

Examine the output of
for F = [-inf,-101:-99,-5:15, 99:101,inf]; disp(F);disp(-pi*10^(F));end
under the format that you want to use.
Notes:
  • format short, format short g, format long, format long g -- none of those correspond exactly to a single sprintf() format, not even when only processing a single number.
  • the output of disp() for a vector or array or multidimensional array can be quite different than the output for a scalar and different than the output of disp() for a different 2D slice of a multidimensional array
  • you need undocumented internal calls to find out which format is currently in effect: matlab.internal.display.format()
  • variables within a table are not displayed with exactly the same format as is used for disp(). Instead, an sprintf() format is used that does not exactly agree with what format would choose
  • The exact output of disp() depends upon the operating system you are running on.
Because of the above factors, I recommend against this course of action. I would instead recommend that you use sprintf() with a fixed format (perhaps chosen considering the data type)
Thank you very much for your response.
  • I understand that output of disp can not be replaced by a single fromat string in sprintf. This is one of the reasons why I asked this question.
  • Output of sprintf to a multidimentional array can be quite weird too. This is why I would like to limit my question only to the case of a scalars.
  • Thank you for info about internal call. At least now I can figure out what is the format type used for disp. May be you have any leads on documentation of format styles?
  • I am not going to use tables for my purpose. I guess for tables matlab uses matlab.mixin.CustomDisplay with their custom implementation of getPropertyGroups. This is kind of what I am trying to do. I just don't want to write extra code figuring out what is the best way to print values when disp does it fine. It feels that there is an internal function (that should be public imo), that does formatting of scalars.
  • I did not expect that disp is different on different platforms. Do you have a link with an article or doc about that?
I understand that it is easier to write single sprintf instead of rewriting disp. But single sprintf does not produce desirable output when input can have any range. I understand that it all boils down to switch statement with ranges of values, I was curious if there a single function that just does the job done. And uses the same format that is set up for console (because why not).
I guess for tables matlab uses matlab.mixin.CustomDisplay with their custom implementation of getPropertyGroups.
No, it does not. It uses loops and num2str() in toolbox/matlab/datatypes/@tabular/disp.m
May be you have any leads on documentation of format styles?
There is no documentation of exactly what the output format is for each case.
I did not expect that disp is different on different platforms
disp() uses C or C++ level library calls that eventually get resolved by operating system libraries. The different operating systems format numbers slightly differently. The most obvious symptom is the number of digits after an exponent, with some platforms using two digits and other platforms using three digits. There are also some differences in how rounding is done (MS Windows having a history of truncating instead of rounding properly).
Also, historically if you requested 16 digits after the decimal point or more with fprintf() or sprintf() or num2str() then MS Windows just output zeros, and Linux output more digits but became inaccurate, and Mac was able to give a perfect representation of the internal binary. (This is what led to the File Exchange contribution num2strexact) This does not affect disp() as disp() does not attempt to output the 16th digit in any of the formats, but it does show you how tied everything is to OS-level routines.
The exact representation from the MS Windows routines changed a couple of years ago; I think it was Windows 10 that finally improved, but I am not at all certain of that.
But single sprintf does not produce desirable output when input can have any range.
What range of values has an undesirable output if you use a %g format of suitable width? Could you give an example of an input that has a different output representation between format long g and fprintf() with a %.15g format and for which you find the %.15g output undesirable ?
Thank you very much for that information. If I understand correctly, sprintf and fprintf also use same C libs, so they have same behaviour as disp under same os.
One of the problems with %.15g is that it prints sometimes too many digits for something simple like 1/3. Sometimes I want to keep output shorter. But also I would like to have all printed numbers to have same length, like disp does (compare disp(0.1) and sprintf('%.15g', 0.1)). But I really like how %#.ng works, where n is number of digits that I get from matlab.internal.display.format().
It seems that my options are either implement my own formatting code using information from internal.display.format, or use evalc trick.
disp([0.1 0.2]) will produce the same output as fprintf('%26.15g%26.15g\n', [0.1 0.2])
Nope.
>> fprintf('%26.15g%26.15g\n', [0.1 0.2])
0.1 0.2
>> disp([0.1, 0.2])
0.1000 0.2000
>> fprintf('%#10.4g%#10.4g\n', [0.1 0.2])
0.1000 0.2000
I should have specified "under format long g as that is the format we were talking about.

Sign in to comment.

 Accepted Answer

matlab.internal.display.containedDisplay(value,width)
formats value according to the current format, provided that the formatted result would be that width or less. If the formatted result would be longer, it returns the empty string ""
There is a lower-level routine matlab.internal.display.containedDisplayHelper that can also accept the format specification to use such as 'longG'; it needs its input packaged a particular way though.
As of R2019b, the internal display routines appear to be:
matlab.internal.display.commandWindowWidth
matlab.internal.display.containedDisplay
matlab.internal.display.containedDisplayHelper
matlab.internal.display.dimensionString
matlab.internal.display.format
matlab.internal.display.formatSpacing
matlab.internal.display.getCellDisplayOutput
matlab.internal.display.getContainedClassName
matlab.internal.display.getDimensionSpecifier
matlab.internal.display.getHeader
matlab.internal.display.getNewlineCharacter
matlab.internal.display.getObjectHeaderHelper
matlab.internal.display.isDesktopInUse
matlab.internal.display.isHot
matlab.internal.display.language
matlab.internal.display.numericDisplay
matlab.internal.display.numericDisplayHelper
matlab.internal.display.printWrapped
matlab.internal.display.truncateLine
matlab.internal.display.wrappedLength
Some of those have .m source in toolbox/matlab/lang/+matlab/+internal/+display but most are built-in.

1 Comment

Thank you. containedDisplay if exactly what I was looking for.

Sign in to comment.

More Answers (1)

>> x=logspace(1,3,10)
x =
1.0e+03 *
0.0100 0.0167 0.0278 0.0464 0.0774 0.1292 0.2154 0.3594 0.5995 1.0000
>> disp(x) % same as above
1.0e+03 *
0.0100 0.0167 0.0278 0.0464 0.0774 0.1292 0.2154 0.3594 0.5995 1.0000
>> str=evalc('disp(x)');
>> fprintf('\nx =\n\n%s', str)
x =
1.0e+03 *
0.0100 0.0167 0.0278 0.0464 0.0774 0.1292 0.2154 0.3594 0.5995 1.0000

1 Comment

Thank you. Works like a charm wrapped in strip. I understand that eval is considered to be evil, but I think that could work as a part of private method of a class.

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!