You can use this non-regex method:
num = 0.112345678
pow = floor(log10(abs(num)));
sprintf('%.8fe%+.3d', num/10^pow, pow)
ans =
1.12345678e-001
For multiple inputs use this:
num= [.123 .456 .789];
pow = floor(log10(abs(num)));
sprintf('%.8fe%+.3d ', [num./10.^pow; pow])
Answer from rahnema1 on Stack OverflowYou can use this non-regex method:
num = 0.112345678
pow = floor(log10(abs(num)));
sprintf('%.8fe%+.3d', num/10^pow, pow)
ans =
1.12345678e-001
For multiple inputs use this:
num= [.123 .456 .789];
pow = floor(log10(abs(num)));
sprintf('%.8fe%+.3d ', [num./10.^pow; pow])
Not sure if this falls under the category of solution or work-around, but here it goes:
x = .123e25; % example number
formatSpec = '%1.8e\n'; % format specification
s = sprintf(formatSpec, x); % "normal" sprintf
pat = '(?<=e)[+-]\d+'; % regex pattern to detect exponent
s = regexprep(s, pat, sprintf('%+04i', str2double(regexp(s, pat ,'match')))); % zero-pad
It uses regular expressions to identify the exponent substring and replace it with the exponent zero-padded to three digits. Positive exponents include a plus sign, as with fprintf.
you can use:
sprintf('%.10f', yourNumber)
Or a more sophisticated option is to use Java-based formatting (see more info , credit to Yair Altman for showing this method), for example:
char(java.text.DecimalFormat('#.00000000').format(yourNumber));
Go to: Preferences > Command view > Numeric Format > bank
There is no way to use directly fprintf format specifier for the format you require. A way around is to use the output of disp as a string to be printed. But disp doesn't return a string, it writes directly to the standard output. So, how to do this?
Here's where evalc (eval with capture of output) comes to the rescue:
%// Create helper function
sdisp = @(x) strtrim(evalc(sprintf('disp(%g)', x)));
%// Test helper function
format ShortEng;
a = 123e-12;
fprintf(1, 'Test: %s', sdisp(a));
This is a workaround, of course, and can backfire in multiple ways because of the untested inputs of the helper functions. But it illustrates a point, and is one of the rare occasions where the reviled eval function family is actually irreplaceable.
You can use the following utility:
http://www.people.fas.harvard.edu/~arcrock/lib118/numutil/unpacknum.m
This will unpack the number also according to a given number N and makes sure that the exponent will be a multiple of N. By putting N=3 you have the Engineering Notation.
More into detail, unpacknum takes 3 arguments: the number x, the base (10 if you want Engineering Notation) and the value N (3 if you want Engineering Notation) and it returns the couple (f,e) which you can use in fprintf().
Check the unpacknum help for a quick example.
In your code, you are assigning a string to a double-float array. It looks like MATLAB automatically converts the string to a double to store it there. Thus, your formatting gets lost:
>> sprintf("%.1e", 1/1000)
ans =
"1.0e-03"
>> a=0;
>> a(1) = sprintf("%.1e", 1/1000)
a =
1.0000e-03
>> class(a)
ans =
'double'
Instead, use a string array:
a = strings(19,1);
%...
a(i-1) = sprintf("%.1e", w);
I'm not used to the new strings, and this behavior surprises me. Assigning a number to a string converts the number to a string, and assigning the string to a number converts it back to a number. This does not happen with the "old-fashioned" char arrays:
>> a=0;
>> a(1) = sprintf('%.1e', 1/1000);
Unable to perform assignment because the left and right sides have a different number of elements.
When using char arrays, store them in a cell array:
a = cell(19,1);
%...
a{i-1} = sprintf('%.1e', w);
You can use "fprintf":
>> fprintf("%.1f\n", pi)
3.1
To show more or less digits just adjust the number after the dot.
If the values to be printed are all less than 10000, you can do the following. (Sorry, only tested in octave.)
octave:62> a = 1.24
a = 1.2400
octave:63> sprintf('%.*f\n', 3-floor(log10(abs(a))), a)
ans = 1.240
octave:64> a = 234.56
a = 234.56
octave:65> sprintf('%.*f\n', 3-floor(log10(abs(a))), a)
ans = 234.6
For more about the expression floor(log10(abs(a))), see How can I get the exponent of each number in a np.array?
If you don't mind exponential notation, another alternative is to use '%.3e' to always get the same number of signficant digits:
octave:70> a = 1.24
a = 1.2400
octave:71> sprintf('%.3e\n', a)
ans = 1.240e+00
octave:72> a = 234.56
a = 234.56
octave:73> sprintf('%.3e\n', a)
ans = 2.346e+02
I decided to build on the answer by Warren, and I wrote a function that should work for both small and large numbers alike. Perhaps someone will improve on this, but I am pleased with it.
function str=sigfigstr(a,sigfigs)
numdecimal = floor(log10(abs(a)));
if sigfigs - numdecimal < 0
str=sprintf('%.0f',round(a,sigfigs,'significant'));
else
str=strip(sprintf('%.*f\n', sigfigs-floor(log10(abs(a))), a));
end
Here are a few examples if it in action in Matlab
>> sigfigstr(.000012431634,3)
ans = '0.0000124'
>> sigfigstr(26666,3)
ans = '26700'