MATLAB - literally convert decimal to string - matlab

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'))

Related

Octave / Matlab - Reading fixed width file

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.

Bitget working with large inputs?

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.

'exact' numerical value after numerical optimization MATLAB

I'm having the following issue with my code. I've been trying to use some other posts that I found on line, like this one. But they didn't what I'm looking for.
My code uses a MATLAB Exchange function which optimize a numerical value that is important to be with 32 digits after the dot such as
0.59329669191989231613604260928696
The optimization function can be found here and it is called fminsearchbnd
The optimization function calculate this and store the value in a variable that I use all over my code. In order not to perform the optimization everytime I want to store the variable (I tried either on a *.mat and on a label in the string form.
But when I retrieve it, MATLAB transforms it in a double precision variable 'cutting' all the numbers after the 14th. However I need all of them because they are important!
Is it possible to read a number like that w/o using vpa() because with a symbolic value I can't do anything.
Any help is really appreciated.
Thanks
EDIT:
fminsearchbnd gives me this class(bb) -> double and when I want to see it on the workspace it is 0.586675392365899. But when I set formatSpec = '%.32f\n'; because I want to see all the numbers that the optimization gives me, typing set(editLabel,'String',num2str(bb,formatSpec))
You're trying to store/use a number that cannot be represented exactly in an IEEE754 64-bit double-precision floating point number.
I'm not sure how you got that number without using vpa() in the first place, since 64-bit double is Matlab's maximum of precision...
You could use the multiple precision toolbox by Ben Barrowes, or HPF by John d'Errico, also from the FEX. You'll have to convert/construct to/from string if you want to store/load it to/from file.
But I have to agree with John's comment there:
The fact is, most of the time, if you can't do it with a double, you
are doing something wrong
so...why exactly are those 32-or-more digits important?

How does one convert from char format to double format, when working with binary numbers?

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))

MATLAB num2str format

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.