quickest way to convert hex to a 16 bit signed integer

64 views (last 30 days)
looking for the quickest way to convert 16 bit hex into a singed 16 bit int
performance is key here.
I was doing it with a type cast before but appears very slow
Anyone have any ideas?
  1 Comment
James Tursa
James Tursa on 29 Jul 2021
Please provide details of exact input and desired output. Is the hex in a char array? What size? What is the exact code you have tried so far?

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 29 Jul 2021
Edited: Walter Roberson on 31 Jul 2021
format long g
N = 100000;
HC = ['0':'9', 'A':'F'];
data = HC(randi(16, N, 4));
timeit(@() typecast(uint16(hex2dec(data)),'int16'), 0)
ans =
0.078666781
timeit(@() typecast(uint16(sscanf(data.', '%4x')),'int16'), 0)
ans =
0.010088781
timeit(@() typecast(cell2mat(textscan(strjoin(cellstr(data),'\n'),'%xu16')),'int16'), 0)
ans =
0.114500781
timeit(@() cell2mat(textscan(strjoin(cellstr(data),'\n'),'%xs16')), 0)
ans =
0.114293781
timeit(@() via_ismember_typecast(data, HC), 0)
ans =
0.003229781
timeit(@() via_ismember_no_typecast(data, HC), 0)
ans =
0.004451781
timeit(@() via_math_typecast(data, HC), 0)
ans =
0.005474781
timeit(@() via_discretize_typecast(data, HC), 0)
ans =
0.005370781
timeit(@() via_lookup_typecast(data,HC), 0)
ans =
0.001278781
function num = via_ismember_no_typecast(data, HC)
[~, dec] = ismember(data, HC);
num = dec(:,1)*4096 + dec(:,2)*256 + dec(:,3) * 16 + dec(:,4);
mask = num > 32767;
num(mask) = num(mask) - 65536;
num = int16(num);
end
function num = via_ismember_typecast(data, HC)
[~, dec] = ismember(data, HC);
dec = dec-1; %bin numbers start with 1
num = typecast(uint16(dec(:,1)*4096 + dec(:,2)*256 + dec(:,3) * 16 + dec(:,4)),'int16');
end
function num = via_math_typecast(data, HC)
dec = data - '0';
mask = dec>9;
dec(mask) = dec(mask) - 7;
num = typecast(uint16(dec(:,1)*4096 + dec(:,2)*256 + dec(:,3) * 16 + dec(:,4)),'int16');
end
function num = via_discretize_typecast(data, HC)
dec = discretize(double(data), double(HC)) - 1; %bin numbers start with 1
num = typecast(uint16(dec(:,1)*4096 + dec(:,2)*256 + dec(:,3) * 16 + dec(:,4)),'int16');
end
function num = via_lookup_typecast(data, HC)
lookup(HC) = 0:15;
dec = lookup(data);
num = typecast(uint16(dec(:,1)*4096 + dec(:,2)*256 + dec(:,3) * 16 + dec(:,4)),'int16');
end
So via_lookup_typecast is the fastest of these, and via_ismember_typecast is second fastest out of all of these possibilities.
If you are doing a lot of these conversions, then the lookup table can be precomputed -- and it is easy to extend the lookup table to handle lowercase as well as upper case.
  6 Comments
Robert Scott
Robert Scott on 6 Aug 2021
Sorry you are incorrect.
2 chars one byte
4 chars two byes
AAAA = 4 chars 2 bytes or one word
An answer was already accepted. Thanks for your interest
Walter Roberson
Walter Roberson on 6 Aug 2021
To clarify the chars represent hex, so even though two chars takes 4 bytes of storage, two char is encoding one byte.

Sign in to comment.

More Answers (0)

Categories

Find more on Numeric Types in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!