MATLAB: How to convert half-precision number into hexadecimal representation

halfhexhexadecimalMATLAB

Hi,
I am using matlab 2019B with support for complex half-precision operations. I want to store my results in a file but fwrite doesn't support class half. Some workaround is to convert to hex and then store as uint16. The problem is that num2hex also doesn't support half class. One way to obtain hexadecimal representation I have found is to use format hex, but parsing output string is not a solution for me.
My question is – Is there any native posibility to store half-precission numbers if file, or convert to hexadecimal representation for further processing?
Best Regards
Adam

Best Answer

I don't have R2019b installed so I don't know how half precision numbers are stored, but can you use typecast:
h = your half precision variable
u16 = typecast(h,'uint16');
Another option is a mex routine, but I would need to know how the half precision values are stored first.
EDIT
I just checked, and unfortunately the new half precision type is not a fundamental numeric type like double or uint16 ... it is an opaque type like OOP classdef objects. So even though isnumeric(half) returns true, half precision variables are not stored the same as the native numeric variables are. The data areas are hidden.
I have no idea why TMW would choose to implement a basic numeric type this way, but they must have their reasons. The half precision type is fundamentally different from all of the other numeric types. Not suprisingly, the typecast( ) function does not work since the storage scheme is fundamentally different. This also makes a mex option out of the question since the data area is hidden. What a pain ... why couldn't they have just made it compatible with all the other numeric types??? THERE WILL BE NO WAY TO EFFICIENTLY WORK WITH HALF VARIBLES IN A MEX ROUTINE BECAUSE OF THIS! (yes I am shouting)
SOLUTION
For your purpose, you only need the hex patterns or equivalent bit patterns to write out. So I can offer my C-mex code for this, which can be found here:
You would convert your half precision variable to single, then call my C-mex routine to turn it into the uint16 half precision bit pattern. Then you can write that uint16 variable directly to a file in binary with fwrite( ). I just need to check to see if it still works in later versions of MATLAB. I will get back to you ...
UPDATE
I downloaded my halfprecision C-mex file and it seems to compile and run OK. Just don't use the -R2018a mex option because the code isn't updated yet for R2018a+. My halfprecision C code will also handle the inf, nan, and denorm patterns just fine. You would compile it as follows:
mex halfprecision.c
Sample run:
>> version
ans =
'9.7.0.1190202 (R2019b)'
>> halfpi = half(pi) % The MATLAB half class
halfpi =
half
3.1406250 % MATLAB is apparently using the single display code for this
>> hp = halfprecision(pi) % my C-mex routine ...
hp =
uint16 % ... returns a uint16 variable that contains the half precision bit pattern
16968
>> halfprecision(hp,'disp') % my C-mex routine has a display option
3.1406
>> halfprecision(hp,'single') % my C-mex routine can convert it back into other classes
ans =
single
3.1406250
>> sprintf('%04x',hp) % If you want the hex values as ASCII text, do this
ans =
'4248'
>>
>> halfinf = half(inf)
halfinf =
half
Inf
>> hinf = halfprecision(inf)
hinf =
uint16
31744
>> halfprecision(hinf,'disp')
Inf
>> halfprecision(hinf,'single')
ans =
single
Inf
>> sprintf('%04x',hinf)
ans =
'7c00'
>>
>> halfnan = half(nan)
halfnan =
half
NaN
>> hnan = halfprecision(nan)
hnan =
uint16
65024
>> halfprecision(hnan,'disp')
NaN
>> halfprecision(hnan,'single')
ans =
single
NaN
>> sprintf('%04x',hnan)
ans =
'fe00'
>> format hex
>> halfpi
halfpi =
half
4248
>> halfinf
halfinf =
half
7c00
>> halfnan
halfnan =
half
fe00