I have a matlab code that its output will print as an input text file for other program. But the numbers format is important in input file of my desired program it should start with 0. and then the number. For example, I want to format the output of Matlab program from the 3.00E+03 to 0.30E+04.
Can anyone between you experts kindly help me?
Many tanx
Please check the reference for fprintf. You can find it in the format specifier:
http://www.mathworks.nl/help/matlab/ref/fprintf.html
Probably the format you desire is not available in MATLAB so you can create your own!
First use log 10 to obtain the power (assuming):
Assuming a number X.
% Number to convert
X = 3867;
% Number of decimals after comma
n = 2;
% Calculation of the power to print
power = floor(log10(X))+1;
% Calculation of the decimals (correctly rounded)
decimals = round(X/10^(power-n));
% The format of fprintf. 0. is static, %d represents the printed decimals, %+0.3d represents the power. + denoting the sign, 0. denoting padding with zeros, 3 denoting the number of characters printed (if less characters in the power padded with zeros).
fprintf('0.%dE%+0.3d',decimals,power)
Kind regards,
Ernst Jan
Related
Let's say I create some number A, of the order 10^4:
A = 81472.368639;
disp(A)
8.1472e+04
That wasn't what I wanted. Where are my decimals? There should be six decimals more. Checking the variable editor shows me this:
Again, I lost my decimals. How do I keep these for further calculations?
Scientific notation, or why you didn't lose any decimals
You didn't lose any decimals, this is just MATLAB's way of displaying large numbers. MATLAB rounds the display of numbers, both in the command window and in the variable editor, to one digit before the dot and four after that, using scientific notation. Scientific notation is the Xe+y notation, where X is some number, and y an integer. This means X times 10 to the power of y, which can be visualised as "shift the dot to the right for y places" (or to the left if y is negative).
Force MATLAB to show you all your decimals
Now that we know what MATLAB does, can we force it to show us our number? Of course, there're several options for that, the easiest is setting a longer format. The most used for displaying long numbers are format long and format longG, whose difference is apparent when we use them:
format long
A
A =
8.1472368639e+04
format longG
A
A =
81472.368639
format long displays all decimals (up to 16 total) using scientific notation, format longG tries to display numbers without scientific notation but with most available decimals, again: as many as there are or up to 16 digits, both before and after the dot, in total.
A more fancy solution is using disp(sprintf()) or fprintf if you want an exact number of decimals before the dot, after the dot, or both:
fprintf('A = %5.3f\n',A) % \n is just to force a line break
A = 81472.369
disp(sprintf('A = %5.2f\n',A))
A = 81472.37
Finally, remember the variable editor? How do we get that to show our variable completely? Simple: click on the cell containing the number:
So, in short: we didn't lose any decimals along the way, MATLAB still stores them internally, it just displays less decimals by default.
Other uses of format
format has another nice property in that you can set format compact, which gets rid of all the additional empty lines which MATLAB normally adds in the command window:
format compact
format long
A
A =
8.147236863931789e+04
format longG
A
A =
81472.3686393179
which in my opinion is very handy when you don't want to make your command window very big, but don't want to scroll a lot either.
format shortG and format longG are useful when your array has very different numbers in them:
b = 10.^(-3:3);
A.*b
ans =
1.0e+07 *
0.0000 0.0001 0.0008 0.0081 0.0815 0.8147 8.1472
format longG
A.*b
ans =
Columns 1 through 3
81.472368639 814.72368639 8147.2368639
Columns 4 through 6
81472.368639 814723.68639 8147236.8639
Column 7
81472368.639
format shortG
A.*b
ans =
81.472 814.72 8147.2 81472 8.1472e+05 8.1472e+06 8.1472e+07
i.e. they work like long and short on single numbers, but chooses the most convenient display format for each of the numbers.
There's a few more exotic options, like shortE, shortEng, hex etc, but those you can find well documented in The MathWork's own documentation on format.
is there any easy way to represent percentage values in Matlab
for example as in excel we can type 8% and it will represent 0.08. the % symbol is suffix to the value.
Try:
a = '%.2f%%';
%.2f%% will show the percentage to 2 decimal places and add a % at the end.
Since the percent character is part of the string formatting syntax, you have to escape it if you want to output its literal:
p = 0.08;
txt = sprintf('%.0f%%',p*100)
txt =
'8%'
For more information, read this page of the official Matlab documentation.
I have a matrix of order 3 x 3, and all elements of matrix are up to 6 decimal place. I want to display this elements of matrix only up to 5 decimal place. I used format short and format long, but it gives either 4 or 15 decimal places.
Is there a command that gives up to any particular decimal places?
I have idea for a single number but could not solve for all entries of a matrix.
The builtin format options cannot handle this. You'll instead want to use fprintf or num2str (with a format specifier) to force the appearance of the number
data = rand(3) * 100;
num2str(data,'%12.5f')
% 20.42155 3.95486 91.50871
% 9.28906 87.24924 72.61826
% 47.43655 95.70325 94.41092
If you want to make this the default display at the command line you could overload the builtin display method for double but I would not recommend that.
Alternately, you can use vpa to specify the number of significant digits to display (note that the second input is the number of significant digits and not the number of numbers after the radix point).
vpa(data, 5)
This question already has answers here:
What is the Small "e" in Scientific Notation / Double in Matlab
(2 answers)
Closed 7 years ago.
How can I write a number/Integer value to power of 10, e.g. 1000 as 10^3? I am writing code whose output is a string of very large numbers. My output in longEng format is:
4.40710646596169e+018
16.9749211806197e+186
142.220634811050e+078
508.723835280617e+204
1.15401317731033e-177
129.994388899690e+168
14.3008811642810e+153
1.25899227268954e+165
24.1450064703939e+150
627.108997290435e+144
2.03728822649372e+177
339.903986115177e-066
150.360900017430e+183
5.39003779219462e+135
183.893417489826e+198
648.544709490386e+045
19.7574461055182e+198
3.91455750674308e+102
6.41548629454028e-114
70.4943280639616e+096
19.7574461055182e+198
3.11450571506133e-009
249.857950606210e+093
4.64921904682151e+180
750.343029004712e+147
I want these results to be in a format of power of 10, so that I can easily do arithmetic operations for my next function.
you can write format shortE and see you output like this:
4.4071e+18
1.6975e+187
1.4222e+80
5.0872e+206
If you only want to print the data in scientific format, the Matlab itself can do this for you.
If you can to obtain the scientific notation form as
a * 10^b,
i.e., obtain the coefficient a and the exponent b, you can first obtain the b as:
b = floor(log10(abs(x)));
then the a as:
a = x * 10^(-b);
from my understanding you wish to take your number e.g. 4.40710646596169e+018 and split it up into:
4.40710646596169 and 018 once you have them separated you you can perform operations as you wish.
You can even join them back to look like: 4.40710646596169^018 if you so desire (although to look like that they would be strings and therefore mathematical operations on the number would be NAN).
Since e represents to the power 10 and is present in all numbers you listed this is a simple process with many solutions, here is one.
% format long is very important otherwise it will appear to you that you have
%lost precision. MATLAB hides precision from view to save screen space and to
%produce less confusing results to the viewer. (the precision is still there but
%with format long you will be able to see it.
format long
x = 4.40710646596169e+018;
%convert your number into a string, this will allow you to split the number based
%on the always present e+ 'delimiter' (not really a delimiter but looks like one')
s = num2str(x);
%use strsplit to perform the split in the required place. it will output a 1x2
%cell
D = strsplit(s, {'e+'});
%extract each cell to a separate variable. in fact D{1} can be directly used for
%the input of the next function.
D11 = D{1};
D22 = D{2};
%convert the separated strings back into numbers with double precision (keep
%maintin value accuracy)
D1 = str2double(D11)
D2 = str2double(D22)
in order to do this operation on an entire column vector it is simply a matter of using a for loop to iterate through all the numbers you have.
I have a very large number of files that were saved in binary in Labview, where each column is a timestamp cluster followed by a vector of singles.
I read each data file into Matlab r2013a using
fid = fopen(filename);
data = fread(fid,[N M],'*single',0,'b');
fclose(fid);
where I pre-calculate the size of the input array N,M. Since I know what the data is supposed to look like, I have figured out that data(1:5,:) is where the timestamp data is hidden, but it looks like something like this for M = 1:
[0 -842938.0625 -1.19209289550781e-07 0 4.48415508583941e-42]
The first element is always 0, the second element decreases monotonically with a constant step size, the third seems to be bistable, flipping back and forth between two very small values, the fourth is always 0, and the fifth is also constant.
I'm assuming it has something to do with how Labview encodes dates, but my google-fu has not helped me figure that out.
To make this a more general question, then:
How does Labview encode a timestamp cluster when it saves to a binary file, and how can I read it out and translate it into a meaningful number in another programming language, such as Matlab?
EDIT:
For posterity, here is my final code (appended to the code above):
datedata = data(5:-1:1,:);
data(1:5,:) = [];
dms = typecast(reshape(datedata(2:3,:),[],1),'uint64');
dsecs = typecast(reshape(datedata(4:5,:),[],1), 'int64');
timestamp = datenum(1904,1,1) + (double(dsecs) + double(dms)*2^-64)/(3600*24);
In the code #Floris posted from Mathworks, they typecast straight to double, but when I tried that, I got garbage. In order to get the correct date, I had to first convert to integer and then to double. Since my bottleneck is in the fread line (0.3 seconds to read off of an external disk), the extra typecast step is miniscule in the grand scheme of things.
The extra column, 4.5e-42, converts to an integer value of 3200, the number of values in the subsequent vector of singles.
This is not a complete answer, but it should help (I don't have either Labview or Matlab available at home so I can't check this right now).
There is an article at http://www.mathworks.com/matlabcentral/newsreader/view_thread/292060 that describes a similar question. Couple of useful bits of information I extracted from that:
Time stamp is a double (not single)
Need to flip the order of bytes (little vs big endian) to make sense of things
There is a useful comment:
Note that the LabView time convention is miliseconds since Jan 1 1904.
Here is one approach (may contain errors but will point you in the
right direction),
The following code snippet is also given:
%% Read in date information
[ fid, msg ] = fopen(FileName, 'r') ;
NColumns = 60 ; % Number of data columns - probably different for your
dataset!
[a, count] = fread(fid, [ NColumns Inf], '*single') ; % Force data to
be read into Matlab workspace as singles
a = a' ; % Convert to data in columns not rows
% The last two columns of a are the timestamp
b = fliplr(a(:, end-1:end)) ; % Must swap the order of the columns
d = typecast(reshape(b',[],1), 'double') ; % Now we can can convert to
double
time_local = datenum(1904, 1, 1) + d/(24*3600) ; % Convert from
seconds to matlab time format
fclose(fid) ;
It looks believable to me. Let me know if it works - if not, I may be able to help debug in the morning...
A LabVIEW timestamp is a 128-bit type consisting of a signed 64-bit integer measuring the offset in seconds since the LabVIEW epoch (January 1, 1904 00:00:00.00 UTC), and an unsigned 64-bit integer measuring the fractional second. Source: ni.com.
The byte order of the file however may be platform dependent. For example the time 8:02:58.147 AM July 3 2013 EDT may be stored as:
0x 00000000CDF9C372 25AA100000000000 (big/network)
or as
0x 000000000010AA25 72C3F9CD00000000 (little)