Is there an easy way to format numbers to 3 significant figures?

919 次查看(过去 30 天)
Is there an easy way to format numbers into scientific notation with 3 significant figures?
Such as:
4.53
or
1.03e+09

回答(5 个)

Jan
Jan 2021-4-28
If "3 significant figures" mean before and after the decimal point:
fprintf('%.3g', pi)
3.14
fprintf('%.3g', pi * 1e9)
3.14e+09
  4 个评论
Walter Roberson
Walter Roberson 2023-2-2
.$ matches any character at the end of the string. To match dot specifically use \.$
PetterE
PetterE about 4 hours 前
Thanks for pointing out that oversight, I have amended my original post.

请先登录,再进行评论。


Steven Lord
Steven Lord 2018-1-30
Use the round function with two input arguments. If this does not work, tell us which release of MATLAB you're using.
round(pi, 2)

Star Strider
Star Strider 2018-1-30
See the documentation on the sprintf (link) function.
A = 6.022140857E+23;
N = sprintf('Avogadro''s number = %9.2E', A)
N =
'Avogadro's number = 6.02E+23'
  2 个评论
Campbell Gray
Campbell Gray 2018-1-30
Does this mean I have to display as a string and not a number?
I currently have my values in a matrix and convert it into a table.
Star Strider
Star Strider 2018-1-30
编辑:Star Strider 2021-4-28
‘Does this mean I have to display as a string and not a number?’
To display it, yes.
MATLAB retains full internal precision, so you lose nothing. The format (link) function is the only way you can control the Command Window and tooltip format.
‘I currently have my values in a matrix and convert it into a table.’
If by ‘table’ you intend the table (link) data type, those appear to have their own internal (and unchangable) format. Formatting options are not listed among the ‘Properties’ in a table, although there may be an undocumented way to change it.
—————
EDIT — (28 Apr 2021 at 20:20)
For the last few MATLAB versions, the round function has had a number of new options added to it, one of which is Round Elements to Specified Number of Significant Digits. It is likely worth upgrading to get these and other enhancements to various functions.
.

请先登录,再进行评论。


John Olesik
John Olesik 2019-1-8
Strickly speaking neither command gives the proper number of significant digits. The correct result for pi in 2 significant digits would be 3.1 with no 0s to the right of the 1. round(pi,2,'significant') gives 3.1000 which as written has 5 significant digits. If you ignore the 0s then it has the correct number of significant digits. round(pi,2) gives 3.1400 which again has 5 significant digits as written (even though the 0s are not correct). round(pi,2) specifies using two non-zero digits to the right of the decimal point, not two significant digits.
  1 个评论
Stephen23
Stephen23 2019-1-8
编辑:Stephen23 2019-1-8
"round(pi,2,'significant') gives 3.1000 which as written has 5 significant digits"
Strickly speaking you are confusing two related but very different things: the precision of the numeric class (which is fixed and cannot be changed) with how numeric values are displayed (which for binary floating point number is often an approximation of the real binary value, as in all of your example values). Floating point numbers are introduced here (and in thousands of tutorials on the internet):
Those five decimal digits (those nice trailing zeros) are simply caused by the current format setting, and are totally independent of any rounding or anything else you might have done to your values beforehand.
Your claim that "the 0s are not correct" is not correct: for the values 3.1 and 3.14 that you show cannot be stored exactly as binary floating point numbers, so the values that you see displayed are approximations of the values that are actually stored in memory: the trailing zeros correctly represent that binary floating point value as a decimal to the precision shown by the zeros:
>> N = round(100*pi)/100
N = 3.1400
>> fprintf('%.40f\n',N)
3.1400000000000001243449787580175325274467
If you want to see the real values stored by the binary floating point class then download James Tursa's excellent num2strExact.

请先登录,再进行评论。


Real User
Real User 2021-4-28
编辑:Real User 2021-4-29
[Fixed] Use this function to format a number to sig significant digits (if you want fixed format, not exponential, and not loose any accuracy of the integer part, or you want to set the maxlength, or the like). For example,
>> fprintf('%s', str_significant(12.34567, 4))
12.35>> fprintf('%s', str_significant(12387654321.987, 3))
12387654322>> fprintf('%s', str_significant(-0.01289, 3, 0, 6)) % 6 = maxlength of the string
-0.013>> fprintf('%s', str_significant(0.01289, 3, 0, 6))
0.0129>>
See further examples below, including the comparison to %.3f and %.3g.
Note: IF YOU WANT TO ROUND ALSO THE INTEGER PART (when it happens to have too many significant digits), uncomment the line above "Uncomment the above line ..." at the end of the comment section.
function str = str_significant(value, sig, minlength, maxlength)
% str = "sprintf(value)" except for minlength and adjusting the number of decimals.
% if round(value) has at least sig digits, use it.
% else: round to so many decimals that you have sig significant digits
% (OR LESS if maxlength requires). (maxlength is used only for this purpose)
% Always: length(str) >= minlength. (Adds leading spaces if necessary.)
% Uses "fixed format", never "exponential format".
%
% N.B. What you see is correctly rounded, if rounding is used
% (but only decimals are rounded away, as many as necessary).
% maxlength is violated iff the integer part is longer than maxlength.
% Matlab may add rounding errors, e.g., after 17 correct digits, so you only see them if you require too many digits.
%
% EXAMPLES: str_significant(12387654321.987, 3) = '12387654322'.
% str_significant(0.00001238, 3) = '0.0000124'.
% str_significant(0.12387654321, 3) = '0.124'. sprintf('%.3g', 12.387654321) = '12.4'.
% str_significant(-0.01289, 3, 8, 6) = ' -0.013'. % 6 = maxlength of the string, 8 = minlength
% str_significant(0.01289, 3, 0, 6) = '0.0129'. str_significant(-35.2987, 7, 0, 6)) = '-35.30'.
% sprintf('%.3f', 0.00001238) = '0.000'. sprintf('%.3g', 1.238) = '1.24'.
% sprintf('%.3g', 1.238e9) = '1.24e+09'. sprintf('%.3g', 1238345.49) = '1.24e+06'.
% sprintf('%.3g', 0.0001238) = '0.000124'. sprintf('%.3g', 0.00001238) = '1.24e-05'.
%
% % value = round(value, sig, 'significant');
% % Uncomment the above line IF YOU WANT TO ROUND ALSO THE INTEGER PART, when it is too accurate.
if (nargin < 4)
maxlength = 999;
if (nargin < 3)
minlength = 0;
end
end
if (value==0)
str = '0';
return;
end
lenint = length(sprintf('%d', round(abs(value)))); % length of the integer part
lenintm = lenint + (value<0); % -"- plus 1 if minus sign
maxdec = max(maxlength-lenintm-1, 0); % lenint+point+decimals <= maxlength required.
if (value >= 1 || value <= -1)
decimals = max(min(sig-lenint, maxdec), 0); % sig-lenint decimals needed.
else
Nzeros = ceil(-log10(abs(value))) - 1; % # zeros after the decimal point before the first number
decimals = min(maxdec, sig + Nzeros);
end
str = sprintf('%*.*f', minlength, decimals, value);
  3 个评论
Jan
Jan 2021-4-29
The usual definition of the term "significant digits" include the digits before the decimal point also.
Real User
Real User 2021-4-29
编辑:Real User 2021-4-30
Yes. If you always want at most sig significant digits (even if it does not save any space), uncomment the line above "Uncomment the above line...". (I now repeated this in capitals in the leading text to avoid people missing this.)
Without uncommenting, the above code rounds down to sig digits only as far as it shortens the output. So you minimize the output by rounding but require at least sig significant digits (unless maxlength forces you to go below that). This is how I needed it to have (to maximize the info but minimize the space), but somebody else might uncomment that line to make the information clearer (but less accurate) even if it does not save any space.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Characters and Strings 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by