quickest way to convert hex to a 16 bit signed integer

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

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

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

Hello Walter
So i did try your "via lookup table function"
I am seeing significant time increases
However, my code is vecotrize.
So what i input for "data" as your argument is actually a NX1 cell array containing a vector of thigns i want this to operate on.
Could you assist with reworking your function to accept this?
That would really be appreciated.
Is the output from this intended to go directly to bit extraction (and not be kept other than for bit extraction)? And is it fixed bits that need to be extracted? The lookup table approach can easily be used for bit extraction, and if that is the end game might as well go there directly, which can reduce the overhead of multiple calls and cell arrays.
Also, your cell arrays... do they always contain the same length of vectors, or variable length? And is there a particular requirement on the class of the returned data? Because if it is fixed length then typically array is the most efficient data structure.
Lets see if i can answer this
So the cell array will always contain 2 byte aka 4 chars
The output needs to be a vector of signed doubles sinces im feeding it a vector of unsigned chars "hex"
so i would expect it to take the vector and spit back a vector of the same length with the now signed doubles.
I tried to adapt your code but have not been succesfull. Im not that familiar with look up tables. hope that answers your questions?
Jan
Jan on 6 Aug 2021
Edited: Jan on 6 Aug 2021
@Robert Scott: "So the cell array will always contain 2 byte aka 4 chars"
4 CHARs use 8 bytes. Please post some example input in Matlab code instead of explaining it in words. James has asked important details already and it is worth to answer such questions for clarifications.
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
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

Products

Release

R2020b

Community Treasure Hunt

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

Start Hunting!