function s = num2str(x, f)
%NUM2STR Convert numbers to character representation
% T = NUM2STR(X) converts the matrix X into its character representation T
% with about 4 digits and an exponent if required. This is useful for
% labeling plots with the TITLE, XLABEL, YLABEL, and TEXT commands.
%
% T = NUM2STR(X,N) converts the matrix X into a character representation
% with a maximum N digits of precision. The default number of digits is
% based on the magnitude of the elements of X.
%
% T = NUM2STR(X,FORMAT) uses the format specifier FORMAT (see SPRINTF for
% details).
%
% Example:
% num2str(randn(2,2),3) produces a character representation such as
%
% ' 1.44 -0.755'
% '0.325 1.37'
%
% Example:
% num2str(pi,'%.2f') produces a character representation such as
%
% '3.14'
%
% See also INT2STR, SPRINTF, FPRINTF, MAT2STR, STRING.
% Copyright 1984-2020 The MathWorks, Inc.
%------------------------------------------------------------------------------
if nargin > 0
x = convertStringsToChars(x);
end
if nargin > 1
f = convertStringsToChars(f);
end
narginchk(1,2);
if ischar(x)
s = x;
return;
end
if isempty(x)
s = '';
return
end
if ~isnumeric(x) && ~islogical(x)
error(message('MATLAB:num2str:nonNumericInput') );
end
if isfloat(x)
x = 0+x; % Remove negative zero
end
if issparse(x)
x = full(x);
end
intFieldExtra = 1;
maxFieldWidth = 12;
floatWidthOffset = 4;
forceWidth = 0;
padColumnsWithSpace = true;
% Compose sprintf format string of numeric array.
if nargin < 2 || (isinteger(x) && isnumeric(f))
% To get the width of the elements in the output string
widthCopy = x;
% replace Inf and NaN with a number of equivalent length (3 digits) for width
% calcultion
if isfloat(x)
widthCopy(~isfinite(widthCopy)) = 314; %This could be any 3 digit number
end
xmax = double(max(abs(widthCopy(:))));
if isequaln(x, fix(x)) && (isinteger(x) || eps(xmax) <= 1)
if isreal(x)
s = int2str(x); % Enhance the performance
return;
end
d = min(maxFieldWidth, floor(log10(xmax)) + 1);
forceWidth = d+intFieldExtra;
f = '%d';
else
% The precision is unspecified; the numeric array contains floating point
% numbers.
if xmax == 0
d = 1;
else
d = min(maxFieldWidth, max(1, floor(log10(xmax))+1))+floatWidthOffset;
end
[s, forceWidth, f] = handleNumericPrecision(x, d);
if ~isempty(s)
return;
end
end
elseif isnumeric(f)
f = round(real(f));
[s, forceWidth, f] = handleNumericPrecision(x, f);
if ~isempty(s)
return;
end
elseif ischar(f)
% Precision is specified as an ANSI C print format string.
% Explicit format strings should be explicitly padded
padColumnsWithSpace = false;
% Validate format string
if ~contains(f,"%")
error(message('MATLAB:num2str:fmtInvalid', f));
end
else
error(message('MATLAB:num2str:invalidSecondArgument'))
end
%-------------------------------------------------------------------------------
% Print numeric array as a string image of itself.
if isreal(x)
[raw, isLeft] = cellPrintf(f, x, false);
[m,n] = size(raw);
cols = cell(1,n);
widths = zeros(1,n);
for j = 1:n
if isLeft
cols{j} = char(raw(:,j));
else
cols{j} = strvrcat(raw(:,j));
end
widths(j) = size(cols{j}, 2);
end
else
forceWidth = 2*forceWidth + 2;
raw = cellPrintf(f, real(x), false);
imagRaw = cellPrintf(f, imag(x), true);
[m,n] = size(raw);
cols = cell(1,n);
widths = zeros(1,n);
for j = 1:n
cols{j} = [strvrcat(raw(:,j)) char(imagRaw(:,j))];
widths(j) = size(cols{j}, 2);
end
end
maxWidth = max([widths forceWidth]);
padWidths = maxWidth - widths;
padIndex = find(padWidths, 1);
while ~isempty(padIndex)
padWidth = padWidths(padIndex);
padCols = (padWidths==padWidth);
padWidths(padCols) = 0;
spaceCols = char(ones(m,padWidth)*' ');
cols(padCols) = strcat({spaceCols}, cols(padCols));
padIndex = find(padWidths, 1);
end
if padColumnsWithSpace
spaceCols = char(ones(m,1)*' ');
cols = strcat(cols, {spaceCols});
end
s = strtrim([cols{:}]);
end
function s = strvrcat(c)
s = strjust(char(c));
end
function [cells, isLeft] = cellPrintf(f, x, b)
try
[cells, err, isLeft] = sprintfc(f, x, b);
if ~isempty(err)
warning(message('MATLAB:num2str:badConversion', err));
end
catch e
warning(e.identifier, '%s', e.message);
cells = {''};
isLeft = false;
end
end
function [s, forceWidth, f] = handleNumericPrecision(x, precision)
if isreal(x)
s = convertUsingRecycledSprintf(x, precision);
forceWidth = 0;
f = '';
else
floatFieldExtra = 6;
s = '';
forceWidth = precision+floatFieldExtra;
f = sprintf('%%.%dg', precision);
end
end
function s = convertUsingRecycledSprintf(x, d)
floatFieldExtra = 7;
f = sprintf('%%%.0f.%.0fg', d+floatFieldExtra, d);
[m, n] = size(x);
scell = cell(1,m);
pads = logical([]);
for i = 1:m
scell{i} = sprintf(f,x(i,:));
if n > 1 && (min(x(i,:)) < 0)
pads(regexp(scell{i}, '([^\sEe])-')) = true;
end
end
s = char(scell{:});
pads = find(pads);
if ~isempty(pads)
pads = fliplr(pads);
spacecol = char(ones(m,1)*' ');
for pad = pads
s = [s(:,1:pad) spacecol s(:,pad+1:end)];
end
end
s = strtrim(s);
end