Extract digits to the right of the decimal point - matlab

e.g. x = 12.354
I want to get 354 from x. For this I tried this equation,
y = x - floor(x)
But this generates 0.354 which is not my requirement.
So, how can I do it?

The generic idea as pointed out by #JoachimPileborg looks like this in MATLAB:
x = 12.354;
str = num2str(x);
idx = find(str=='.');
substr = str(idx+1:end);
y = str2num(substr);

A generic solution that should work with all programming languages, is to convert the number to a string, then take the sub-string from after the decimal point (or comma) and convert it to an integer.

An alternative (possibly faster) to m.s. 's answer. Notice the 'shift' due to this approach effectively removing the zeroes to the right of the decimal point.
yfoo = 34.00267400;
yfoo = yfoo- floor(yfoo); % .00267400;
% internal rep of number ignores trailing zeros.
yrab = str2num(strrep(num2str(yfoo),'.','')); %2674

Related

Matlab reading numbers with higher precision

I have made this scripts that calculates the frequency of a given dataset, but matlab is not precise enough, is it possible to make matlab read in more accurat numbers and not cut off the numbers? I want it to use 8 digits (0.12345678) instead of 4 (0.1234) that is does now
fid = fopen('forceCoeffs.dat','rt');
A = textscan(fid, '%f%f%f%f%f%f', 'HeaderLines',9,'Collect', 9);
A = A{1};
fclose(fid);
t = A(:,1);
Fs = 1/(A(1,1));
x = A(:,2)
x = detrend(x,0);
xdft = fft(x);
freq = 0:Fs/length(x):Fs/2;
xdft = xdft(1:length(x)/2+1);
plot(freq,abs(xdft));
[~,I] = max(abs(xdft));
fprintf('Maximum occurs at %d Hz.\n',freq(I));
File: https://drive.google.com/file/d/0B9CEsYCSSZUSb1JmcHRkbFdWYUU/view?usp=sharing
Thank you for including the forceCoeffs.dat file as it allowed me to run your code. Here is an explanation of what you are seeing.
First I want to point out that MATLAB is not rounding anything. You can check the data type of A to ensure you have enough precision.
>> class(A)
ans =
double
And since you are reading in the file using %f for each column, MATLAB will use all the bits provided by the double type. Ok, now take a look at the contents of your file. The first column has only 2 decimals of precision at most.
0.05 -7.013874e-09 1.410717e+02 -6.688450e-02 -3.344226e-02 -3.344224e-02
...
349.95 -1.189524e-03 1.381022e+00 -2.523909e-01 -1.273850e-01 -1.250059e-01
350 -1.423947e-03 1.380908e+00 -2.471767e-01 -1.250123e-01 -1.221644e-01
Since no more is needed MATLAB only prints four decimal places when you look at the variable in the variable explorer. Try looking at one of the other columns to see what I am talking about. I commented out the A = A{1} part of your code and looked at the second column. When clicking on the number you see the full precision.
You can use a long type to display 16 digits
To get more than 4 digits precision, you can use
format long
However, to get exactly 8 digits, you need to round it. If your number is a then let use:
format long
round(1e8*a)*1e-8

Calculate the percentage in Matlab

I want to calculate the percentage of accuracy. I have the code below. But it give unexpected output like this "The accuracy is 2.843137e+01x37".
While expected result is "The accuracy is 28.43%"
y %Amount of correct data
j %Amount of all data
a = 'The accuracy is %dx%d.';
percent = '%.0f%%';
format short
acc = 100 * double(y/j);
sprintf (a,acc)
How to fix it?
Any help would be so much appreciated.
Thank you.
You almost have what you expected, just put it together the right way.
The correct format specifier for 28.43% is %.2f%%. This gives you two digits after the decimal point and adds the %-sign at the end. You have that defined in the variable percent, except that .0 should be .2 for two digits as you have written in the expected result. If you look closely, you'll realize that percent is never used.
Let's come to the conclusion. Change the format specifier to the following:
a = 'The accuracy is %.2f%%';
That's all you need to do. The line defining percent can be omitted as well as format short unless you need this for something later on.
Something important regarding the cast to double: What you currently have just casts the result. If necessary, do the cast individually to y and/or j before the division. Probably you don't need any casting in your case.
The whole code with an assumption for y and j is:
y = 28.43137; %// Amount of correct data
j = 100; %// Amount of all data
a = 'The accuracy is %.2f%%';
acc = 100 * (y/j); %// no cast
% acc = 100 * (double(y)/double(j)); %// with cast
sprintf(a,acc);
Output:
ans =
The accuracy is 28.43%
Try,
a = 'The accuracy is %f.';
acc = 100 * double(y/j);
sprintf (a,acc)

Elegant way of finding all integer element indices in a MATLAB array?

I have a double array containing a mixture of integers and doubles. I wish to get all the indices of the integer elements. My way (see below) is quite ugly.
idx_list = [];
for idx = 1:numel(A)
if isinteger(A(idx))
idx_list = [idx_list idx];
end
end
I believe there is a one liner / a more elegant way.
Something like this would find perfect integers -
idx_list = find( floor(A) == A )
Changing floor to ceil or round or fix should do it too.
If you want to take care of floating point precision issues, you can introduce eps here -
idx_list = find(abs(round(A) - A)<eps(round(A)))

How to add leading zeros in MatLab (number formatting)?

Here is a very specific example
>> S = num2str(12345,'%6.0e')
S =
1e+04
and that's just great since I want only my first digit and an exponential notation. However I also want to add leading zeros to the exponent in order to fill the width, but I cannot quite find the way to get the following...
1e+004
Meanwhile it's very straighforward to pad the significant digits with leading zeros
>> S = num2str(12345,'%06.0e')
S =
01e+04
So is there an appropriate formatting for what I want? Or a trick to accomplish it quickly?
The exponent is always a zero-padded two-digit value. To add, say, two zeros you can use
regexprep(num2str(12345, '%6.0e'), '\+', '\+00')
and achieve
ans =
1e+0004
Edit: To cover negative exponents you may use
regexprep(num2str(0.12345, '%6.0e'), '(\+|\-)', '$100')
to achieve
ans =
1e-0001
And, to cover three-digit exponents
regexprep(num2str(1e-100, '%6.0e'), '(\+|\-)(\d{2,3})$', {'$10$2', '$10$2'})
ans =
1e-0100
regexprep(num2str(1e-10, '%6.0e'), '(\+|\-)(\d{2,3})$', {'$10$2', '$10$2'})
ans =
1e-0010
Well, I think you have to edit, what you say you want is wat you get :D
however, if I understood correctly what you are looking for, this function will help you
function printX(x, digits)
format = sprintf('\t%%.%de', digits - 1);
strcat(inputname(1), ' = ', sprintf(format, x))
end

How can I cast variables in matlab with fixed floating point

Is it possible convert a double variable to a float (single in Matlab) with fixed floating point?
For example
x = 10.023213032130123021302130210331232132103312321
to
x = 10.0231
Thank you !
First convert to single:
X = single(Y)
And than apply round() to get fixed format:
X = round(10^N*X) / 10^N;
to get N digits behind the decimal point