Converting a list of binary numbers to a decimal numbers

조회 수: 9 (최근 30일)
Martin Mittrenga
Martin Mittrenga 2022년 8월 12일
편집: Martin Mittrenga 2022년 8월 13일
Dear Matlab Community,
for my study i have to convert a list of numbers from binary to decimal (fraction and integer).
And thats my code:
close all;
clear all;
load('accumulator_output.dat');
accumulator_output_string = num2str(accumulator_output);
S = strsplit(accumulator_output_string,'.');
intV = S{1} - '0';
fracV = S{2} - '0';
intValue = intV * (2 .^ (numel(intV)-1:-1:0).')
fracValue = fracV * (2 .^ -(1:numel(fracV)).')
result = intValue + fracValue;
It works best for a single value in the list. How do I get Matlab to convert the whole list?
When I tried more than one value in the list, matlab will respons this errors:
Error using regexp
The 'STRING' input must be either a char row vector, a cell array of char row vectors, or a string array.
Error in strsplit (line 125)
[c, matches] = regexp(str, aDelim, 'split', 'match');
Error in Test (line 8)
S = strsplit(accumulator_output_string,'.');
Many thanks
-Martin

채택된 답변

Jan
Jan 2022년 8월 12일
편집: Jan 2022년 8월 12일
Replace
load('accumulator_output.dat');
accumulator_output_string = num2str(accumulator_output);
by
S = readlines('accumulator_output.dat');
To avoid the conversion of chars to numbers and back to chars and to numbers...
Avoid names like "accumulator_output_string", because they provoke typing errors.
Then process the string array element by element:
X = zeros(size(S));
for k = 1:numel(S)
X(k) = Binary2Dec(S{k});
end
function result = Binary2Dec(C)
S = strsplit(C, '.');
intV = S{1} - '0';
fracV = S{2} - '0';
intValue = intV * (2 .^ (numel(intV)-1:-1:0).');
fracValue = fracV * (2 .^ -(1:numel(fracV)).');
result = intValue + fracValue;
end
If you do have the code to convert 1 string, simply call it in a loop to do it for an array of strings.

추가 답변 (2개)

John D'Errico
John D'Errico 2022년 8월 12일
편집: John D'Errico 2022년 8월 12일
You have a list of binary numbers, as a character array. So zeros, ones, and a decimal point. (Personally, I think that should be called a bicimal point.) For example:
BiNum = ['0001.1101';'0101.0111';'1000.0001';'0000.1000']
BiNum = 4×9 char array
'0001.1101' '0101.0111' '1000.0001' '0000.1000'
If we can assume all of the bicimal points lie at the same location, then it is truly trivial. First, locate the bicimal point.
bicimalind = strfind(BiNum(1,:),'.')
bicimalind = 5
Once we know the location, we can remove them.
BiNum(:,bicimalind) = ''
BiNum = 4×8 char array
'00011101' '01010111' '10000001' '00001000'
Finally, reconstitute the numbers in true decimal form, first as integers.
BiNumBits = size(BiNum,2);
DecNum = (BiNum - '0')*2.^(BiNumBits-1:-1:0)'
DecNum = 4×1
29 87 129 8
All that remains now is to put the bicimal point back in, as an effective bit shift.
DecNum = DecNum*2^(bicimalind - BiNumBits - 1)
DecNum = 4×1
1.8125 5.4375 8.0625 0.5000
As you can see, fully vectorized. It only required that the bicimal points were in the same position for all numbers. If that was not true, then you would need to work slightly harder, but not a lot. You might do the above proces for every row, separately, in a loop. God forbid, a loop. In fact though, it would not take a lot of effort to do that in a vectorized form either.
A nice thing is, as long as your numbers are limited to no more than 52 bits, then these computations will result in EXACT values for those decimal numbers in double precision. That is because doubles are themselves stored in a binary form internally. In fact, this points out you could have done the above computations by converting the numbers into a proper hexadecimal form, then casting that result into a double. IMHO, probably more mental effort than it is worth, since the above computation was so easy.)
Finally, I would point out that IF your numbers have more than 52 bits, you will not be able to convert them in this way, since a double precision number is limited to 52 bits. Could it still be done, using carefully written code? Of course. I know that to be true, as the guy who has written several high precision arithmetic codes in MATLAB, so I know of what I speak. :)

Jeffrey Clark
Jeffrey Clark 2022년 8월 12일
@Martin Mittrenga, read up on num2str and strsplit which don't really support vectors of things. One way to do this without loops is to use cell instead. Change num2str to r = cell(string(__)) and embed strsplit in a call to cellfun(@(x) strsplit(__),r). See MATLAB documentatinand and examples for these.

카테고리

Help CenterFile Exchange에서 Data Type Conversion에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by