I was looking for a way to separate the digits of an array in Matlab i.e.
if A = 1024 then I would like it to be A = [1, 0, 2, 4].
I searched on the net and found this code (also posted on the title):
sprintf('%d',A) - '0'
which converted [1024] -> [1, 0, 2, 4].
It did solve my problem but I did not understand it, especially the - '0' part.
can someone please explain how this works?
Also if I write sprintf('%d',A) + '0' (for A = [1024]) in MATLAB command window then it showed the following:
97 96 98 100
this puzzled me even more can anyone explain this?
It takes advantage of the automatic casting from a char array to a double array when the - operator is used. Remember that each character has an ascii value so if you type
double('0') in the command line and you'll see you get 48 as an answer. While double('1024') gives you
ans =
49 48 50 52
sprintf('%d', A) just convert the integer to a string (i.e. a char array). The minus casts both sides to double so you end up with
double('1024') - double('0')
which is
[49, 48, 50, 52] - [48]
which ends up as [1,0,2,4]
From here it should be clear why adding '0' resulted in [97, 96, 98, 100]
The command sprintf('%d',A) converts integer A=1024 into a string representation of the number, '1024'.
In addition, a string in matlab is really a character array, so if A = '1024' then A(1) = '1'.
The rest of the explanation follows from the answer #Dan posted. When numeric operations (+ - * / mod ^ ...) are applied to character arrays they are converted to the equivalent numeric representation according to the ASCII code, retaining the array format as type double.
Related
I'd like to have a function generate(n) that generates the first n lowercase characters of the alphabet appended in a string (therefore: 1<=n<=26)
For example:
generate(3) --> 'abc'
generate(5) --> 'abcde'
generate(9) --> 'abcdefghi'
I'm new to Matlab and I'd be happy if someone could show me an approach of how to write the function. For sure this will involve doing arithmetic with the ASCII-codes of the characters - but I've no idea how to do this and which types that Matlab provides to do this.
I would rely on ASCII codes for this. You can convert an integer to a character using char.
So for example if we want an "e", we could look up the ASCII code for "e" (101) and write:
char(101)
'e'
This also works for arrays:
char([101, 102])
'ef'
The nice thing in your case is that in ASCII, the lowercase letters are all the numbers between 97 ("a") and 122 ("z"). Thus the following code works by taking ASCII "a" (97) and creating an array of length n starting at 97. These numbers are then converted using char to strings. As an added bonus, the version below ensures that the array can only go to 122 (ASCII for "z").
function output = generate(n)
output = char(97:min(96 + n, 122));
end
Note: For the upper limit we use 96 + n because if n were 1, then we want 97:97 rather than 97:98 as the second would return "ab". This could be written as 97:(97 + n - 1) but the way I've written it, I've simply pulled the "-1" into the constant.
You could also make this a simple anonymous function.
generate = #(n)char(97:min(96 + n, 122));
generate(3)
'abc'
To write the most portable and robust code, I would probably not want those hard-coded ASCII codes, so I would use something like the following:
output = 'a':char(min('a' + n - 1, 'z'));
...or, you can just generate the entire alphabet and take the part you want:
function str = generate(n)
alphabet = 'a':'z';
str = alphabet(1:n);
end
Note that this will fail with an index out of bounds error for n > 26, so you might want to check for that.
You can use the char built-in function which converts an interger value (or array) into a character array.
EDIT
Bug fixed (ref. Suever's comment)
function [str]=generate(n)
a=97;
% str=char(a:a+n)
str=char(a:a+n-1)
Hope this helps.
Qapla'
I am looking for a way to convert an array of 16-bit unsigned integer into ASCII char array. I am using char to do the conversion
D=[65 65 65 65];
char(D)
which will show 4 'A'. However, since each number in D is 16-bit, I expect it to convert each number to 2 chars. For example, if I have
D=[16707]
char(D)
I expect it gives me two chars 'A' and 'C'. But char always return 1 character. Is that anyway to force char to convert like the way I stated? Thanks.
For this, you need to write your own function.
You can use char() to convert most significant byte and least significant byte separately.
k = 16707;
first = char(bitand(bitshift(k, -8), 255));
second = char(bitand(k, 255));
Have a look at
http://www.mathworks.com/help/matlab/ref/char.html
It cleatly states that the char function is valid only for 8 bit numbers. you can convert each part of cell of the array with this and contact the results for each two cells.
Use typecast to convert each uint16 to two uint8, and then apply char. Make sure that the input to typecastr is really of type uint16.
If you need to reverse char order, use swapbytes on the uint16 vector.
>> D = [16707 16708];
>> char(typecast(uint16(D),'uint8'))
ans =
CADA
>> char(typecast(swapbytes(uint16(D)),'uint8'))
ans =
ACAD
I'm fairly new to Matlab, although not to programming. I'm trying to hash a string, and get back a single value that acts as a unique id for that string. I'm using this DataHash function from FileExchange which returns the hash as an integer vector. So far the best solution I've found for converting this to a single numeric value goes:
hash_opts.Format = 'uint8';
hash_vector = DataHash(string, hash_opts);
hash_string = num2str(hash_vector);
% Use a simple regex to remove all whitespace from the string,
% takes it from '1 2 3 4' to '1234'
hash_string = regexprep(hash_string, '[\s]', '');
hashcode = str2double(hash_string);
A reproducible example that doesn't depend on DataHash:
hash_vector = [1, 23, 4, 567];
hash_string = num2str(hash_vector);
% Use a simple regex to remove all whitespace from the string,
% takes it from '1 2 3 4' to '1234'
hash_string = regexprep(hash_string, '[\s]', '');
hashcode = str2double(hash_string); % Output: 1234567
Are there more efficient ways of achieving this, without resorting to a regex?
Yes, Matlab's regex implementation isn't particularly fast. I suggest that you use strrep:
hashcode = str2double(strrep(hash_string,' ',''));
Alternatively, you can use a string creation method that doesn't insert spaces in the first place:
hash_vector = [1, 23, 4, 567];
hash_string = str2double(sprintf('%d',hash_vector))
Just make sure that your hash number is less than 2^53 or the conversion to double might not be exact.
I'v seen there's already an answer - though it loses precission as it omits leading 0s - I'm not really sure if it will cause you troubles but I wouldn't want to rely on it.
As you output as uint8 why don't you use hex values instead - this will give you the exactly same number. Converting back is also easy using dec2hex.
hash_vector = [1, 23, 4, 253]
hash_str=sprintf('%02x',hash_vector); % to assure every 8 bit use 2 hex digits!
hash_dig=hex2dec(hash_str)
btw. - your sampe hash contains 567 - an impossible number in uint8.
Having looked at DataHash the question would also be why not use base64 or hex in the first place.
i donot know why there is error in this coding:
hex_str1 = '5'
bin_str1 = dec2bin(hex2dec(hex_str1))
hex_str2 = '4'
bin_str2 = dec2bin(hex2dec(hex_str2))
c=xor(bin_str1,bin_str2)
the value of c is not correct when i transform the hex to binary by using the xor function.but when i used the array the value of c is correct.the coding is
e=[1 1 1 0];
f=[1 0 1 0];
g=xor(e,f)
what are the mistake in my first coding to xor of hec to binary value??anyone can help me find the solution...
Your mistake is applying xor on two strings instead of actual numerical arrays.
For the xor command, logical "0"s are represented by actual zero elements. Any non-zero elements are interpreted as logical "1"s.
When you apply xor on two strings, the numerical value of each character (element) is its ASCII value. From xor's point of view, the zeroes in your string are not really zeroes, but simply non-zero values (being equal to the ASCII value of the character '0'), which are interpreted as logical "1"s. The bottom line is that in your example you're xor-ing 111b and 111b, and so the result is 0.
The solution is to convert your strings to logical arrays:
num1 = (bin_str1 == '1');
num2 = (bin_str2 == '1');
c = xor(num1, num2);
To convert the result back into a string (of a binary number), use this:
bin_str3 = sprintf('%d', c);
... and to a hexadecimal string, add this:
hex_str3 = dec2hex(bin2dec(bin_str3));
it is really helpful, and give me the correct conversion while forming HMAC value in matlab...
but in matlab you can not convert string of length more than 52 character using bin2dec() function and similarly hex2dec() can not take hexadecimal character string more than 13 length.
I have a vector, for example, V = [ 1, 2, 3, 4 ]. Is there a way to change this to the letters, [ a,b,c,d ]?
Using 'a' directly instead of ascii codes might be slightly more readable
charString = char(V-1+'a');
Uppercase is then obtained with
charString = char(V-1+'A');
There are two simple ways to do this. One way is a simple index.
C = 'abcdefghijklmnopqrstuvwxyz';
V = [8 5 12 12 15 23 15 18 12 4];
C(V)
ans =
helloworld
Of course, char will do it too. The char answer is better because it does not require you to store a list of letters to index into.
char('a' + V - 1)
ans =
helloworld
This is best since when you add 'a' to something, it converts 'a' to its ascii representation on the fly. +'a' will yield 97, the ascii form of 'a'.
A nice thing is it also works for 'A', so if you wanted caps, just add 'A' instead.
char('A' + V - 1)
ans =
HELLOWORLD
You can find more information about working with strings in MATLAB from these commands:
help strings
doc strings
Something like
C = char(V+ones(size(V)).*(97-1))
should work (97 is the ASCII code for 'a', and you want 1 to map to 'a' it looks like).
Using the CHAR function, which turns a number (i.e. ASCII code) into a character:
charString = char(V+96);
EDIT: To go backwards (mapping 'a' to 1, 'b' to 2, etc.), use the DOUBLE function to recast the character back to its ASCII code number:
V = double(charString)-96;