# swapbytes order problem with uint64?

7 views (last 30 days)
Tony Tse on 10 Sep 2017
Commented: Walter Roberson on 10 Sep 2017
I find that swapbytes doesn't seem to be behaving correctly for my problem. I have a 64 bits hexidecimal string printed in big-endian: 'b0120c0a7799ba3e'
Manually swapping the bytes give me the expected answer:
typecast(uint64(hex2dec('3eba99770a0c12b0')), 'double')
ans =
1.5855e-06
If I follow the example code in swapbytes however, it seems behave incorrectly. Either:
typecast(swapbytes(uint64(hex2dec('b0120c0a7799ba3e'))), 'double')
ans =
3.5031e-305
or
typecast(uint64(swapbytes(hex2dec('b0120c0a7799ba3e'))), 'double')
ans =
0
The function seem to work correctly for a single precision hexadecimal:
typecast(swapbytes(uint32(hex2dec('0cc9d435'))),'single')
ans =
single
1.5854e-06
Am I missing something, I can certainly write some loops to parse the string but is there a better solution?

Matt J on 10 Sep 2017
Edited: Matt J on 10 Sep 2017
I suspect the problem is actually in hex2dec(). You are exceeding the flintmax limit described in the hex2dec documentation:
d = hex2dec('hex_value') converts hex_value to its floating-point integer representation. The argument hex_value is a hexadecimal integer stored as text. If the value of hex_value is greater than the hexadecimal equivalent of the value returned by flintmax, then hex2dec might not return an exact conversion.

Matt J on 10 Sep 2017
Tony Tse commented:
That actually makes a lot of sense so I definitely need to swap the order of the hex string before conversion wit my own routine before conversion then. Thanks.
Matt J on 10 Sep 2017
Even if you swap the hex string yourself, I suspect you still have to make sure the swapped result obeys flintmax.
Tony Tse on 10 Sep 2017
In my case, because the string comes from real measured data. I think it should be never by out of range? so ended just up doing something like this:
s = 'b0120c0a7799ba3e';
s = fliplr(s);
ii = 1;
while ii < length(s)
s([ii ii+1]) = s([ii+1 ii]);
ii = ii + 2;
end
typecast(uint64(hex2dec(s)), 'double');
Actually, hex2num should work without conversion to decimal now since I am not using swapbytes and don't need to typecast:
hex2num(s)

Walter Roberson on 10 Sep 2017
Do not use hex2dec() for this purpose. Use sscanf()
sscanf('b0120c0a7799ba3e', '%lx')
ans =
uint64
12687216339351878206
%lx is an unsigned 64 bit format.