I'm storing variable values in MATLAB and putting one of the variable values as part of the file name . e.g. "Error=1e-003.mat", however different version of MATLAB gives me different format when I'm converting numbers to string using num2str command. The number 1e-3, MATLAB2011 gives me 1e-003 and MATLAB2012 gives me 1e-03.
This runs into trouble when I try to load a batch of files with a mix of those two format. Does anyone know a way to add a zero or delete a zero for the exponent so the names are consistent? Or any other ways to solve this problem?
Here's a fairly robust way to do it:
A = num2str(YOUR_NUMBER, '%0.0e');
if A(end-2)=='-' || A(end-2)=='+'
A = [A(1:end-2) '0' A(end-1:end)]; end
In words: convert the number, and check if the second-to-last character is either a '+' or a '-'. If this is so, add a '0'.
Specify a "Format string as the second argument like this:
>> disp(num2str(2920230,'%0.10e'))
2.9202300000e+006
here %0.10e means display at least 0 digits before decimal and exactly 10 digits after it in exponent form.
Related
I hope I have a simple question, I just couldn't figure it out.
I have several numbers which I want to be converted to string quite literally:
12.000 -> '12.000'
4.0 -> '4.0'
34.760000 -> '34.760000'
As you can see, I cannot simply pad zeros, since that highly depends on how many zero are given with the number.
Does anyone know how to do this?
Ahh, yes, this is easily accomplished with MATLAB's num2str function, like so:
num2str(12.000 ,'%.3f')
num2str(4.0, '%.1f')
num2str(34.760000,'%.6f')
WRT " %x.f ", where x equals 3,1, and 6 in the examples above, this is called the formSpec, which I would encourage you to read about more, here. In this case, we are saying that the variable is a floating point number, and we want to preserve x digits after the decimal place. It is useful to know about format specification for parsing text, and to efficiently read from and write to files.
Edit: A point of clarification, and as I'm sure you already know, single quotes (' ') in MATLAB yield a character array rather than a string. These are different data types. If you're really after a string, just add string to the num2str argument, i.e.,
string(num2str(12.000 ,'%.3f'))
string(num2str(4.0, '%.1f'))
string(num2str(34.760000,'%.6f'))
I am using Matlab 2018b on Windows 10. I understand that the Matlab string concatenation needs input arguments under concatenation to be a character array, a cell array of character vectors, or a string array as mentioned in https://de.mathworks.com/help/matlab/ref/strcat.html. Based on this i was expecting an error while trying to do the following:
[1, 'some_string']
or
strcat(1, 'some_string')
But i am not getting any error message. Instead getting output as displayed in the snapshot below:
Based on below, looks like automatic type conversion is taking place for 1 from double to char but seems something in getting wrong in the process resulting in 1 being replaced with a junk char. Any insight in to this please?
x = strcat(1, 'some_string');
class(x(1))
ans =
'char'
Matlab is treating the 1 as an ascii code, corresponding to the start of heading character which is being displayed as the square you see.
It is more obvious what Matlab is doing if you e.g. do strcat(65, 'some_string'), which returns Asome_string as the ascii code 65 corresponds to a capital A.
I have a fixed width file format (original was input for a Fortran routine). Several lines of the file look like the below:
1078.0711005.481 932.978 861.159 788.103 716.076
How this actually should read:
1078.071 1005.481 932.978 861.159 788.103 716.076
I have tried various methods, textscan, fgetl, fscanf etc, however the problem I have is, as seen above, sometimes because of the fixed width of the original files there is no whitespace between some of the numbers. I cant seem to find a way to read them directly and I cant change the original format.
The best I have come up with so far is to use fgetl which reads the whole line in, then I reshape the result into an 8,6 array
A=fgetl
A=reshape(A,8,6)
which generates the following result
11
009877
703681
852186
......
049110
787507
118936
So now I have the above and thought I might be able to concatenate the rows of that array together to form each number, although that is seeming difficult as well having tried strcat, vertcat etc.
All of that seems a long way round so was hoping for some better suggestions.
Thanks.
If you can rely on three decimal numbers you can use a simple regular expression to generate the missing blanks:
s = '1078.0711005.481 932.978 861.159 788.103 716.076';
s = regexprep(s, '(\.\d\d\d)', '$1 ');
c = textscan(s, '%f');
Now c{1} contains your numbers. This will also work if s is in fact the whole file instead of one line.
You haven't mentioned which class of output you needed, but I guess you need to read doubles from the file to do some calculations. I assume you are able to read your file since you have results of reshape() function already. However, using reshape() function will not be efficient for your case since your variables are not fixed sized (i.e 1078.071 and 932.978).
If I did't misunderstand your problem:
Your data is squashed in some parts (i.e 1078.0711005.481 instead
of 1078.071 1005.481).
Fractional part of variables have 3 digits.
First of all we need to get rid of spaces from the string array:
A = A(~ismember(A,' '));
Then using the information that fractional parts are 3 digits:
iter = length(strfind(A, '.'));
for k=1:iter
[stat,ind] = ismember('.', A);
B(k)=str2double(A(1:ind+3));
A = A(ind+4:end);
end
B will be an array of doubles as a result.
The default type is uint64 but the below apparently requires larger support where you can see that the number 536870915 (100000000000000000000000000011 in binary, 30 bits' length) is not supported by the above bitget command. So
How to get bitget command working with large inputs like the below?
Input
hhhh=sparse([],[],[],2^40+1,1);
hhhh(536870915)=1;
bitget(str2num(dec2bin(find(hhhh)-1)),2,'uint64')
Output
Error using bitget
Double inputs must have integer values in the range of ASSUMEDTYPE.
You pass the output of dec2bin(find(hhhh)-1) to str2num. This directly converts the string of ones and zeros into a double: 9.999999999999999e+28. I'm guessing that's not what you want.
If you're just trying to get the second bit of 536870915, why not use:
bitget(find(hhhh)-1,2,'uint64')
On the other hand, I think that you could also use this (probably slower, but maybe it'll work with the rest of your code if you're already converting to string representation):
b = dec2bin(find(hhhh)-1);
str2double(b(end-1))
It seems like you're trying to combine two approaches.
I have a piece of code which outputs what I want but in the wrong format
for k=1:100
bin(k,:)=dec2bin(randi([0 31]),5);
end
I want the output to be a 100x5 double array, with one bit per cell (0 or 1 value).
I've tried using the double() function...
for k=1:100
bin(k,:)=double(dec2bin(randi([0 31]),5));
end
...but that returns the correct format, with the wrong values.
My jargon might be a bit off, I apologise (Am I using cell, double, etc in the wrong context?)
Thank you for helping me.
There are a lot of ways to do what you want. The simplest would actually be generating the binary array right from the start, without a loop:
bin = rand(100, 5) > 0.5
Other alternatives:
If you have an integer array and you want to convert it to bits, you can use bitget instead of dec2bin inside the loop:
bin(k, :) = bitget(randi([0 31]), 5:-1:1)
If you already have a string array representing binary numbers, and you want to operate on it, you can delimit the bits with spaces and then apply str2num:
bin = reshape(str2num(sprintf('%c ', bin)), size(bin))