hello i have entered some text and convert it to the binary values.these binary values get stored in a array of data type double. Now i want to get the char array from that array containing binary values.
text2='hello how are u';
text3=double(text2);
nValues = numel(text3);
B=8;
bit_stream = zeros(1,nValues*B);
% eight bit for binary representation of each character.
for iBit = 1:B %# Loop over the bits
bit_stream(iBit:B:end) = bitget(text3,B-iBit+1); %# Get the bit values
end
bitstream=bit_stream;
how to perform vice-versa..
text2_recovered = char( 2.^(7:-1:0) * reshape(bit_stream, 8, []) );
Explanation:
Arrange bits in groups of 8 (reshape(...,8,[]));
Convert each group to a byte value (2.^(7:-1:0)*...) ;
Convert those bytes to characters (char).
Related
sample input:
B15
sample output:
B15 in binary = 1011000010101
I've tried
a = input()
print(bin(a))
The hexadecimal number 0xB15 = 2837 has the binary representation 0b101100010101. So if your input is a hexadecimal number, you need to tell Python to convert the string "B15" which comes out of input() into the hexadecimal number 0xB15, also known as the decimal number 2837, before you can convert it into binary for output.
BASE = 16
a = int(input(), BASE)
print(bin(a)[2:]) # Cut of the first two characters '0b'
tl;dr
I'm just looking for two functions, f from double to string and g from string to double, such that g(f(d)) == d for any double d (scalar and real double).
Original question
How do I convert a double to a string or char array in a reversible way? I mean, in such a way that afterward I can convert that string/char array back to double retrieving the original result.
I've found formattedDisplayText, and in some situations it works:
>> x = eps
x =
2.220446049250313e-16
>> double(formattedDisplayText(x, 'NumericFormat', 'long')) - x
ans =
0
But in others it doesn't
x = rand(1)
x =
0.546881519204984
>> double(formattedDisplayText(x, 'NumericFormat', 'long')) - x
ans =
1.110223024625157e-16
As regards this and other tools like num2str, mat2str, at the end they all require me to decide a precision, whereas I would like to express the idea of "use whatever precision is needed for you (MATLAB) to be able to read back your own number".
Here are two simpler solutions to convert a single double value to a string and back without loss.
I want the string to be a human-readable representation of the number
Use num2str to obtain 17 decimal digits in string form, and str2double to convert back:
>> s = mat2str(x,17)
s =
'2.2204460492503131e-16'
>> y = str2double(s);
>> y==x
ans =
logical
1
Note that 17 digits are always enough to represent any IEEE double-precision floating-point number.
I want a more compact string representation of the number
Use matlab.net.base64encode to encode the 8 bytes of the number. Unfortunately you can only encode strings and integer arrays, so we type cast to some integer array (we use uint8 here, but uint64 would work too). We reverse the process to get the same double value back:
>> s = matlab.net.base64encode(typecast(x,'uint8'))
s =
'AAAAAAAAsDw='
>> y = typecast(matlab.net.base64decode(s),'double');
>> x==y
ans =
logical
1
Base64 encodes every 3 bytes in 4 characters, this is the most compact representation you can easily create. A more complex algorithm could likely convert into a smaller UTF-8-encoded string (which uses more than 6 bytes per displayable character).
Function f: from double real-valued scalar x to char vector str
str = num2str(typecast(x, 'uint8'));
str is built as a string containing 8 numbers, which correspond to the bytes in the internal representation of x. The function typecast extracts the bytes as a numerical vector, and num2str converts to a char vector with numbers separated by spaces.
Function g: from char vector str to double real-valued scalar y
y = typecast(uint8(str2double(strsplit(str))), 'double');
The char vector is split at spaces using strsplit. The result is a cell array of char vectors, each of which is then interpreted as a number by str2double, which produces a numerical vector. The numbers are cast to uint8 and then typecast interprets them as the internal representation of a double real-valued scalar.
Note that str2double(strsplit(str)) is preferred over the simpler str2num(str), because str2num internally calls eval, which is considered evil bad practice.
Example
>> format long
>> x = sqrt(pi)
x =
1.772453850905516
>> str = num2str(typecast(x, 'uint8'))
str =
'106 239 180 145 248 91 252 63'
>> y = typecast(uint8(str2double(strsplit(str))), 'double')
y =
1.772453850905516
>> x==y
ans =
logical
1
How do I call out a particular digit from a number. For example: bringing out 6 from 768, then using 6 to multiply 3. I've tried using the code below, but it does not work.
digits = []
digits = str(input("no:"))
print (int(digits[1] * 5))
If my input is 234 since the value in[1] is 3, how can I multiply the 3 by 5?
input() returns a string (wether or not you explicitly convert it to str() again), so digits[1] is still a single character string.
You need to convert that single digit to an integer with int(), not the result of the multiplication:
print (int(digits[1]) * 5)
All I did was move a ) parenthesis there.
Your mistake was to multiply the single-character string; multiplying a string by n produces that string repeated n times.
digits[1] = '3' so digits[1] * 5 = '33333'. You want int(digits[1]) * 5.
I have two lists of strings as a column in a table (PM25_spr{i}.MonitorID and O3_spr{i}.MonitorID). The lists are of different lengths. I want to compare the first 11 characters of each entry and pull out the index for each list where they are the same.
Example
List 1:
'01-003-0010-44201'
'01-027-0001-44201'
'01-051-0001-44201'
'01-073-0023-44201'
'01-073-1003-44201'
'01-073-1005-44201'
'01-073-1009-44201'
'01-073-1010-44201'
'01-073-2006-44201'
'01-073-5002-44201'
'01-073-5003-44201'
'01-073-6002-44201'
List 2:
'01-073-0023-88101'
'01-073-2003-88101'
'04-013-0019-88101'
'04-013-9992-88101'
'04-013-9997-88101'
'05-119-0007-88101'
'05-119-1008-88101'
'06-019-0008-88101'
'06-029-0014-88101'
'06-037-0002-88101'
'06-037-1103-88101'
'06-037-4002-88101'
'06-059-0001-88101'
'06-065-8001-88101'
'06-067-0010-88101'
'06-073-0003-88101'
'06-073-1002-88101'
'06-073-1007-88101'
'08-001-0006-88101'
'08-031-0002-88101'
I tried intersect, which isn't the right approach for what I want to do. I'm not sure how to use ismember given that I only want to look at the first 11 characters.
I tried strncmp, but Inputs must be the same size or either one can be a scalar.
chars2compare = length('18-097-0083');
strncmp(O3_spr{i}.MonitorID, PM25_spr{i}.MonitorID,chars2compare)
PM25_spr_MID = cell(length(years),1); % Preallocate cell array
for n = 1:length(PM25_spr{i}.MonitorID)
s = char(PM25_spr{i}.MonitorID(n)); % Convert string to char
PM25_spr_MID{i}(n) = cellstr(s(1:11)); % Pull out 1-11 characters and convert to cell
end
O3_spr_MID = cell(length(years),1); % Preallocate cell array
for n = 1:length(O3_spr{i}.MonitorID)
s = char(O3_spr{i}.MonitorID(n));
O3_spr_MID{i}(n) = cellstr(s(1:11));
end
[C, ia, ib] = intersect(O3_spr_MID{i}, PM25_spr_MID{i})
PerCap_spr_O3{i} = O3_spr{i}(ia,:);
PerCap_spr_PM25{i} = PM25_spr{i}(ib,:);
Assuming list1 and list2 to be the two input cell arrays, you can use few approaches.
I. Operate on cell arrays
With intersect -
%// Clip off after first 11 characters in each cell of the input cell arrays
list1_f11 = arrayfun(#(n) list1{n}(1:11),1:numel(list1),'uni',0)
list2_f11 = arrayfun(#(n) list2{n}(1:11),1:numel(list2),'uni',0)
%// Use intersect to find common indices in the input cell arrays
[~,idx_list1,idx_list2] = intersect(list1_f11,list2_f11)
With ismember -
%// Clip off after first 11 characters in each cell of the input cell arrays
list1_f11 = arrayfun(#(n) list1{n}(1:11),1:numel(list1),'uni',0)
list2_f11 = arrayfun(#(n) list2{n}(1:11),1:numel(list2),'uni',0)
%// Use ismember to find common indices in the input cell arrays
[LocA,LocB] = ismember(list1_f11,list2_f11);
idx_list1 = find(LocA)
idx_list2 = LocB(LocA)
II. Operate on char arrays
We can use char dierctly on the input cell arrays to get 2D char arrays as working with them could be faster than working withcells.
With intersect + 'rows' -
%// Convert to char arrays
list1c = char(list1)
list2c = char(list2)
%// Clip char arrays after first 11 columns
list1c_f11 = list1c(:,1:11)
list2c_f11 = list2c(:,1:11)
%// Use intersect with 'rows' option
[~,idx_list1,idx_list2] = intersect(list1c_f11,list2c_f11,'rows')
III. Operate on numeric arrays
We can convert the char arrays further to numeric arrays with just one column as that could lead to faster solutions.
%// Convert to char arrays
list1c = char(list1)
list2c = char(list2)
%// Clip char arrays after first 11 columns
list1c_f11 = list1c(:,1:11)
list2c_f11 = list2c(:,1:11)
%// Remove char columns of hyphens (3 and 7 for the given input)
list1c_f11(:,[3 7])=[];
list2c_f11(:,[3 7])=[];
%// Convert char arrays to numeric arrays
ncols = size(list1c_f11,2);
list1c_f11num = (list1c_f11 - '0')*(10.^(ncols-1:-1:0))'
list2c_f11num = (list2c_f11 - '0')*(10.^(ncols-1:-1:0))'
This point onwards you have three more approaches to work with that are listed next.
With ismember ( would be memory efficient, but maybe not fast across all datasizes) -
[LocA,LocB] = ismember(list1c_f11num,list2c_f11num);
idx_list1 = find(LocA)
idx_list2 = LocB(LocA)
With intersect (could be slow) -
[~,idx_list1,idx_list2] = intersect(list1c_f11num,list2c_f11num)
With bsxfun ( would be memory inefficient, but maybe fast for small to decent sized inputs) -
[idx_list1,idx_list2] = find(bsxfun(#eq,list1c_f11num,list2c_f11num'))
I want to create a binary number in matlab and am having difficulty concatenating the numbers.
Here's what I tried so far:
testarray = zeros(10,10)
testarray = num2str(testarray) % Convert all values to type string
testarray(1,1) = num2str(1); % Fill with abitrary value
testarray(1,1) = strcat(testarray(1,1), num2str(0)); % Trying to make '10' here but instead I get this error: "Assignment has more non-singleton rhs dimensions than non-singleton subscripts"
Any help would be appreciated.
In your example, the problem is that '10' has size [1,2], but testarray(1,1) has size [1,1]. So you might consider using cells instead:
testarray = cell(5,5);
testarray{1,1} = strcat(testarray(1,1), num2str(0));
By the way, you should have a look at the function dec2bin.
From the documentation:
dec2bin(23)
ans =
10111
The resulting value is a string.
So if you want to concatenate two binary values (encoded as strings), just do:
['10' '11']
ans =
1011