Is there an easy way to format numbers to 3 significant figures?
조회 수: 914 (최근 30일)
이전 댓글 표시
Is there an easy way to format numbers into scientific notation with 3 significant figures?
Such as:
4.53
or
1.03e+09
댓글 수: 1
D Huntsman
2018년 9월 25일
round(var,digit,'significant')
where var is the variable of interest and digit is number of significant digits.
답변 (5개)
Jan
2021년 4월 28일
If "3 significant figures" mean before and after the decimal point:
fprintf('%.3g', pi)
fprintf('%.3g', pi * 1e9)
댓글 수: 4
Walter Roberson
2023년 2월 2일
.$ matches any character at the end of the string. To match dot specifically use \.$
PetterE
2024년 11월 21일 10:46
Thanks for pointing out that oversight, I have amended my original post.
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)
댓글 수: 0
Star Strider
2018년 1월 30일
A = 6.022140857E+23;
N = sprintf('Avogadro''s number = %9.2E', A)
N =
'Avogadro's number = 6.02E+23'
댓글 수: 2
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
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
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
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
2021년 4월 29일
The usual definition of the term "significant digits" include the digits before the decimal point also.
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 Center 및 File Exchange에서 Characters and Strings에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!