extracting data from hex

Asked by Luisa Cencha

Luisa Cencha (view profile)

on 28 May 2019
Latest activity Commented on by Guillaume

Guillaume (view profile)

on 29 May 2019
Dear all,
I have a .dat file whit hex data. I used 'readtable' to extract the info, but now I want to convert it to decimal using hex2dec. However I had the following error,
Error using hex2num>hex2decImpl (line 57)
Input to hex2num should have just 0-9, a-f, or A-F.
Error in hex2num (line 25)
x = hex2decImpl(char(s));
The lines I used,
a.(3)=hex2num(a.(3))
..and a part of the data I'm trying to convert,
{'0x0000D830'}
{'0x000103EA'}
{'0x000105C1'}
{'0x000079B5'}
{'0x0000E24D'}
{'0x0000BB9F'}
{'0x0000A28F'}
There is any way of remove the 0x000 part? Or any other idea to convert and plot the hex data?
Thanks a lot!

Guillaume (view profile)

on 29 May 2019
Edited by Guillaume

Guillaume (view profile)

on 29 May 2019

Easiest way is to use sscanf instead of hex2dec. sscanf with the '%x' format specifier understand '0x' notation directly:
>> sscanf('0x000103EA', '%x')
ans =
66538
With your table the simplest way to convert everything would be:
t = fillmissing(t, 'constant', '0x0', 'DataVariables', @iscellstr); %replace empty entries by 0x0 for cellstr variables
t = convertvars(t, @iscellstr, @(var) cellfun(@(x) sscanf(x, '%x'), var)) %convert cellstr variables to numbers with sscanf
Note that you may want to store the numbers as uint32 instead of double, in which case that last line becomes:
t = convertvars(t, @iscellstr, @(var) cellfun(@(x) uint32(sscanf(x, '%x'), var)))
One of the major advantage of sscanf over hex2dec is that it can decode 64-bit hexadecimal integers (with the '%lx' format). hex2dec will return rounded results for integers above flintmax:
>> sscanf('0xFFFFFFFFFFFFFFFE', '%lx') %returns the correct result
ans =
uint64
18446744073709551614
>> uint64(hex2dec('FFFFFFFFFFFFFFFF')) %returns an incorrect result due to the conversion to double
ans =
uint64
18446744073709551615

Rik (view profile)

on 28 May 2019

You should only remove the leading 0x as that indicates the data is hexadecimal.
data_hex={{'0x0000D830'}
{'0x000103EA'}
{'0x000105C1'}
{'0x000079B5'}
{'0x0000E24D'}
{'0x0000BB9F'}
{'0x0000A28F'}};
data_dec=cellfun(@(x) hex2dec(x{1}(3:end)),data_hex);

Luisa Cencha

Luisa Cencha (view profile)

on 29 May 2019
Here is the data sample, thank you so much!
Rik

Rik (view profile)

on 29 May 2019
You can use Guillaume's suggestion, but the code below works (and fills empty positions with NaN).
aa=table2cell(a);
data_dec=cellfun(@parse_fun,aa(:,3:6));
%if you are sure there are no empty cells you don't need parse_fun
%data_dec=cellfun(@(x) hex2dec(x(3:end)),aa(:,3));
function val=parse_fun(str)
if ~isempty(str)
val=hex2dec(str(3:end));
else
val=NaN;
end
end
Guillaume

Guillaume (view profile)

on 29 May 2019
Rather than converting to cell, you can work directly on the table with rowfun, varfun or convertvar:
a = convertvar(a, 3:6, @(var) cellfun(@parsefun, var))