Converting floating-point hexadecimal (string input) to decimal

조회 수: 6 (최근 30일)
YC
YC 2020년 4월 17일
댓글: YC 2020년 4월 22일
I am trying to convert a base-16 string input to a base-10 output. I have a current code, using the hex2dec function. However, it won't convert a hex input with a floating point. Is there any way I can do so? For example. input '2B.3A' should return output 43.2265625
I would also like to convert base 10 inputs to base 16, so if anyone has any links for such files, it would be a great help. Thank you for your time
%Input must be a string
function y = hex2double(n)
n = strtrim(n);
c=0;
i=1;
if isempty(find(n=='.', 1))
y = hex2dec(n);
else
j = find(n=='.');
intp=n(1:j-1);
floatp=n(j+1:end);
%if find 0 in the beginning of the fraction part
%-divide by [place-value needed] times (1+ number of 0's), add floating part to integer part
%after that:
%floatp=floatp/(10*(1+c));
%this is where things get out of hand
y = hex2double(intp)+hex2dec(floatp);
end

채택된 답변

Stephen23
Stephen23 2020년 4월 17일
편집: Stephen23 2020년 4월 18일
>> str = '2B.3A';
>> out = sscanf(str,'%lx.'); % use NUMEL(OUT) to detect integer or fractional
>> dcp = numel(str)-strfind(str,'.');
>> out = out(1) + out(2) ./ pow2(4*dcp)
out =
43.2265625
A more challenging example:
>> str = '3.243F6A8885A2F7A'; % π
>> out = sscanf(str,'%lx.');
>> dcp = numel(str)-strfind(str,'.');
>> out = out(1) + out(2) ./ pow2(4*dcp)
out =
3.14159265358979
Note that more than 16 integer digits or 16 fractional digits will not be correctly parsed by this method, and the output precision is limited by the double type anyway.
For the reverse conversion the usual method is:
  1. scale the fractional part by 16,
  2. convert the integer part to hexadecimal,
  3. repeat from step one until you run out of digits or reach some precision limit.
You will find plenty of examples of this method on the internet.
Alternatively, if you don't mind a few trailing zeros, it can be done in one step:
>> num = 43.2265625;
>> str = sprintf('%X.%016X',fix(num),mod(num,1)*pow2(64))
str = 2B.3A00000000000000
Or a more challenging example:
>> num = pi
num = 3.141592653589793
>> str = sprintf('%X.%016X',fix(num),mod(num,1)*pow2(64))
str = 3.243F6A8885A30000
  댓글 수: 7
Stephen23
Stephen23 2020년 4월 22일
"I receive out = 43 with blue text utint64"
Ah, that would explain it. On earlier MATLAB versions (like 2012b that I am using) sscanf returns a double for that format specifier, but apparently at some point TMW upgraded sscanf and it now returns an integer type. You can probably get it working with either of these:
out = sscanf(str,'%x.'); % remove 'l' -> returns double
out = double(sscanf(str,'%lx.')); % wrap in DOUBLE
Try both of them and then pick whichever one suits your needs best.
YC
YC 2020년 4월 22일
Alright, thank you! I'll upload my own response sometime as well, just in case anyone finds it helpful

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 MATLAB에 대해 자세히 알아보기

제품


릴리스

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by