2

I have a number A=7654321.

I need the number at location 5 (from beginning, or number 3 from end), which in this case is 3.

Is there a function which does something like: getdigit(A,n), where A is the number and n is the position of the number that I want?

I could convert the number to a text string, find the number at position n, and convert it back to a number (num2str and str2double), but it does not seem like a good solution to me, are there any better ways you know of?

Autonomous
  • 8,935
  • 1
  • 38
  • 77
ROLF
  • 284
  • 2
  • 14

2 Answers2

4

The most efficient way I can think of is to do exactly what you didn't want to do, though slightly more efficient! Convert your number to a string, break up each digit into separate locations, then pull out the digit you want. Therefore:

function [out] = getDigit(A,n)
C = num2str(A) - 48;
out = C(n);
end

The first statement is a bit tricky. Use num2str to convert your number into a character array. Now, you need to know a bit about MATLAB internals for what I'm about to do next. By casting the string to double, it will convert each character into its ASCII representation and place each character into a separate entry in a numeric array, which assigns a unique ID to each character that exists on your keyboard. You'll notice that the number zero starts at ID 48, and linearly increases from there. As such, I subtract by 48 to bring the numbers back to 0-9. In fact, if you just subtract the string by 48, it will automatically be cast to double for you (thanks Luis!).

Once I do this, I pick out the position I want, which is n. Therefore, after running this by doing C = getdigit(7654321, 5);, we get:

C = 

3

However, if you really really don't want to do use the ASCII trick, you can use information about dividing by powers of 10 and remainders.... actually, Anders Forsgren linked you to a nice post in Java, but let's do that in MATLAB.

Simply take the modulus of A by 10^n, divide this by 10^(n-1) and take the floor. However, one caveat is that this method counts from the end, so you would have to make n equal to 3.

Therefore:

function [out] = getDigit(A,n)
out = floor(mod(A, 10^n) / 10^(n-1));
end

Doing C = getDigit(7654321, 3) gives us:

C =

3

Edit

If you want to stick with your convention and go from left to right, rather than right to left, you can calculate how many digits exist in the number, then simply use the logic that I have above and wrap around by taking your value of n and subtracting this from the number of digits minus one (borrowed from badjr). Therefore:

function [out] = getDigit(A,n)
n = (floor(log10(A)) + 1) - (n - 1);
out = floor(mod(A, 10^n) / 10^(n-1));
end

The first part of recalculating n is to determine how many digits we have to represent our number. We need to take n and reformulate it so that we are referring to the digit position from right to left, rather than left to right. This is in order to use the logic I defined previously. You need to make sure that you wrap around by subtracting with n - 1, because if you subtracted with just n, this actually makes the extract zero-indexed based. If you want to respect your function definition where n = 1 is the first digit of the number to extract and not the second, we have to offset by 1.

By doing C = getDigit(7654321, 5);, we get:

C =

3
rayryeng
  • 102,964
  • 22
  • 184
  • 193
0

Defining a function getdigit(A, n) (in a file getdigit.m):

function d = getdigit(A, n)
    numDigits = floor(log10(abs(A))) + 1;
    d = mod(floor(A/10^(numDigits - n)), 10);
end

Then,

>>A=7654321;
>>getdigit(A, 5)

gives

ans =

     3
badjr
  • 2,166
  • 3
  • 20
  • 31