Convert floating point or double base-10 value to any other base using dec2base?

12 views (last 30 days)
Hello, here I have a code which converts base-10 values to any other base below 10.
%Input must be a string
%Converts base-10 value to any other base under 10
%Use only numeric input
function y = fdec2base(str,n)
if isempty(find(str=='.', 1))
y = dec2base(str2double(str),n);
else
str = lower(str);
d = strfind(str,'.');
intp = str(1:d-1);
decp = str(d+1:end);
if isempty(decp)
y=dec2base(str2double(intp),n);
else
p=length(decp)+1;
decp=str2double(decp);
decpf=decp*n*(10^(-p));
y = dec2base(str2double(intp),n);
y=str2double(y)+decpf;
end
end
end
How can I use this to convert base-10 values to higher order bases? I've already started on modifying the above code but I'm struggling to create a while loop which executes the commented procedure effectively. What the while-loop should do is multiply decimal part by input base n, convert integral part of result to base n using dec2base, repeat until fractional part is 0, and align converted elements backwards using reverse(). How can I make this happen? Thanks in advance.
%Input must be a string
%Converts base-10 value to any other base
%Use only numeric input
function y = fdec2base(str,n)
if n < 11
if isempty(find(str=='.', 1))
y = dec2base(str2double(str),n);
else
d = strfind(str,'.');
intp = str(1:d-1);
decp = str(d+1:end);
if isempty(decp)
y=dec2base(str2double(intp),n);
else
p=length(decp)+1;
decp=str2double(decp);
decpf=decp*n*(10^(-p));
y = dec2base(str2double(intp),n);
y=str2double(y)+decpf;
end
end
else
if isempty(find(str=='.', 1))
y = dec2base(str2double(str),n);
else
d = strfind(str,'.');
intp = str(1:d-1)
decp = str(d+1:end)
q = decp;
decpf=string([]);
if isempty(decp)
y=dec2base(str2double(intp),n);
else
while q > 0
%multiply decp by n
decp = str2double(str(d:end)) * n;
d2 = strfind(decp,'.');
decp_int = str(d2+1:end)
decpf = decpf + num2str(dec2base(decp_int,n))
%convert integral part of result to base n using dec2base
%repeat until fractional part is 0
%align converted elements backwards
end
decpf
y = dec2base(str2double(intp),n)+reverse(decpf)
end
end
end
end
  1 Comment
Stephen23
Stephen23 on 22 Apr 2020
Edited: Stephen23 on 22 Apr 2020
This line will produce nonsense:
y=str2double(y)+decpf;
The output is a binary floating point number whose decimal representation at some particular precision just happens to have some digits that just happen to correspond to the representation of some other number in a different base. You cannot apply any meaningful mathematical operations on it and expect that they will be performed in that different base. The concept is flawed (and it also gives an incorrect output).
The output of dec2base has type char simply because other bases are NOT displayed by any of MATLAB's inbuilt numeric displaying operations (e.g. in the Command Window, Variable Viewer, fprintf, etc., some of which display hexadecimal, but certainly do NOT support displaying numerics in an arbitrary base).
Note that this is entirely a question of displaying the value, the underlying binary floating point number does not change, no matter what base you represent it in, because it is the same value (this is why your concept is flawed, because you are actually changing the numeric value to something else only vaguely related to the input numeric value). Imagine if MATLAB implemented some routine pickbase that let us display numerics in any base then we could do something like
>> pickbase(10) % Does NOT exist, just a thought experiment!
>> A = 7;
>> pickbase(3)
>> A
A = 21
and the binary floating point number A stored in MATLAB's memory HAS NOT CHANGED, because bases only affect how numbers are represented, not their actual values. This is why your numeric output makes no sense: you function basically returns that 21 and you are claiming that it is in base 3. Sure... try adding 2 to it, and see if that addition is performed in base 3. (hint: it isn't, you will get 23 and not 100).
Defining the decimal input to be a string is strange: much better would be numeric, just like dec2base**.
Also note that you will run into trouble with lines like this:
while q > 0
because you also need to consider that representations of a value can easily have infinite fractional digits (consider 0.1(decimal) in binary, or 0.1(trinary) in decimal), although in practice this is limited by the precison of binary floating point numbers and/or realmin.
You also need to think about what that while loop is actually doing (for example, what is the point of detecting the decimal point inside the loop?).
I don't see any reason why you need to treat bases >10 any differently from bases <10, most likely they can all be handled using exactly the same code. In fact you probably don't even need different hanlding for the integer and fractional parts, one loop is likely enough.
I suggest that you should:
  1. focus first on actually understanding how to convert from numeric to any base by simply using numeric vectors of digits (much like John D'Errico's FEX submission base2base), rather than strings.
  2. build up a good collection of test cases that you have first checked yourself, and then double-checked using some online conversion tool. Test your code thoroughly with them, at each step of development.
  3. consider using just one loop (and doing the entire conversion yourself is probably simpler than mixing it up with dec2base).
** which really is misnamed: the input numeric is either integer or binary floating point, neither of which actually know anything about base 10 (or any other random base, with the possible exception of binary).

Sign in to comment.

Answers (0)

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!