Easier/Faster way to convert Hex numbers to binary?
Mostrar comentarios más antiguos
I have an input file that has multiple columns of data, I am only interested in two of them. Right now I have both columns importing into MatLab and the first one, timestamps, is fine and I don't have any problems with it. The next one however, is a HEX number in the format 0x ####, I don't like how long it takes to run.
Currently I'm importing my dataArray,
filename = 'D:\MatLab Files\Import Files\InputFile.txt';
delimiter = ',';
startRow = 2;
formatSpec = '%*s%s%*s%s%s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'HeaderLines' ,startRow-1, 'ReturnOnError', false);
fclose(fileID);
dataArray{1} = datenum(dataArray{1}, 'HH:MM:SS.FFF');
Timestamp = dataArray{:, 1};
then having to run:
MsgInfo = dec2bin(hex2dec(cellfun(@(x)(x(4:end)),dataArray{:, 2}, 'UniformOutput', false)),16);
This gets me my variable into a 16 character binary number so that I can then get the bits I need out of the data. I have a total of seven bits that get set depending on if there are any errors detected in the data stream. This is how I'm currently doing this:
% using the sum function to total the number of times the bit is set to 1, giving me the total number of errors for each error type
ManchesterErrors = sum(bind2dec(MSGInfo(:,16)));
ParityErrors = sum(bind2dec(MSGInfo(:,15)));
OverRunErrors = sum(bind2dec(MSGInfo(:,14)));
TimeOutErrors = sum(bind2dec(MSGInfo(:,13)));
BroadcastMsg = sum(bind2dec(MSGInfo(:,11)));
ModeCodeNoData = sum(bind2dec(MSGInfo(:,10)));
TotalMessageErrors = sum(bind2dec(MSGInfo(:,9)));
However, this adds a lot of time (30+ minutes) to my data analysis. I'm hoping to speed this up. I found the following on the forums,
typecast(uint16(sscanf('MYHEXSTRINGHERE', '%x')), 'int16')
and tried to do this:
MSGInfoHexNumbers = cellfun(@(x)(x(4:end)),dataArray{:, 2},'UniformOutput',false); %outputs a Nx1 cell array (iscellstr = 1)
MSGInfoBinaryNumbes = typecast(uint16(sscanf(MSGInfoHexNumbers,'%x')),'int16');
but I can't get it to work for my data. I keep getting the error "First argument must be a string".
I'm using MatLab R2012b if this helps when providing answers, and I've attached a sample file (Test File.txt) of my input data, and a copy of my code to date (Hex 2 binary help.txt).
Respuestas (2)
Walter Roberson
el 23 de Dic. de 2015
MSGInfoBinaryNumbes = cellfun(@(S) typecast(uint16(sscanf(S(4:end),'%x')),'int16'), dataArray(:,2) );
5 comentarios
dpb
el 23 de Dic. de 2015
Ah, see you also had similar idea, Walter. I tried to get an fscanf format written to parse directly but never managed to get it to work correctly (oh, what I'd give for FORMAT strings).
I don't for the life of me understand why TMW doesn't implement '%X' formatting in textscan and friends; I forget whether I've actually submitted it as enhancement request or whether it's also one of the many they've ignored over untold years. :(
It's always seemed TMW thinks dealing with machine words and the like is beneath the dignity of Matlab users or we're supposed to be above such menial fray in the RAD world, I don't know, but it surely can be frustrating.
joshmartinmont
el 23 de Dic. de 2015
Walter Roberson
el 23 de Dic. de 2015
bitget()
joshmartinmont
el 23 de Dic. de 2015
Try the profiler???
I'm not sure you need the typecast nor uint16 (altho they're not likely contributing much), do you? I also don't know if a format string of '0x %X' and eliminating the substring addressing would help much or not, but I'd give it a shot.
Friedrich Welck
el 22 de Mzo. de 2016
MsgInfo = dec2bin(hex2dec(cellfun(@(x)(x(4:end)),dataArray{:, 2}, 'UniformOutput', false)),16);
is slow (cellfun is rarely fast). hex2dec, base2dec etc. work fastest on character arrays. Try
dataArray{2} = char(dataArray{2});
MsgInfo = dec2bin(base2dec(dataArray{2}(:,4:7),16),16);
Also there's no need to convert back to decimal for summation of errors. Try
ManchesterErrors = sum(MsgInfo(:,16)=='1');
ParityErrors = sum(MsgInfo(:,15)=='1');
OverRunErrors = sum(MsgInfo(:,14)=='1');
TimeOutErrors = sum(MsgInfo(:,13)=='1');
BroadcastMsg = sum(MsgInfo(:,11)=='1');
ModeCodeNoData = sum(MsgInfo(:,10)=='1');
TotalMessageErrors = sum(MsgInfo(:,9)=='1');
Categorías
Más información sobre Data Type Conversion en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!