swapbytes order problem with uint64?

3 ビュー (過去 30 日間)
Tony Tse
Tony Tse 2017 年 9 月 10 日
コメント済み: Walter Roberson 2017 年 9 月 10 日
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
Matt J 2017 年 9 月 10 日
編集済み: Matt J 2017 年 9 月 10 日
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.
  3 件のコメント
Matt J
Matt J 2017 年 9 月 10 日
Even if you swap the hex string yourself, I suspect you still have to make sure the swapped result obeys flintmax.
Tony Tse
Tony Tse 2017 年 9 月 10 日
編集済み: Tony Tse 2017 年 9 月 10 日
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)

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2017 年 9 月 10 日
Do not use hex2dec() for this purpose. Use sscanf()
sscanf('b0120c0a7799ba3e', '%lx')
ans =
uint64
12687216339351878206
%lx is an unsigned 64 bit format.
  2 件のコメント
Tony Tse
Tony Tse 2017 年 9 月 10 日
Thanks! This worked perfectly.
typecast(swapbytes(sscanf('b0120c0a7799ba3e', '%lx')), 'double')
Walter Roberson
Walter Roberson 2017 年 9 月 10 日
If you are working with something that is an IEEE double, then
swapbytes(hex2num('b0120c0a7799ba3e'))

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by