37

Example. 123456, and we want the third from the right ('4') out.

The idea in practise is to access each digit seperately (ie. 6 5 4 3 2 1).

C/C++/C# preferred.

John Smith
  • 631
  • 1
  • 6
  • 7
  • 2
    You need to clarify - are you looking for decimal digits? If so, bit-wise operations are not appropriate. Are you looking for binary, octal or hexadecimal digits? If so, then bit-wise operations are appropriate. Also, they are 'integers', not 'intergers' (title). – Jonathan Leffler Oct 15 '08 at 06:24

12 Answers12

40

A more efficient implementation might be something like this:

char nthdigit(int x, int n)
{
    while (n--) {
        x /= 10;
    }
    return (x % 10) + '0';
}

This saves the effort of converting all digits to string format if you only want one of them. And, you don't have to allocate space for the converted string.

If speed is a concern, you could precalculate an array of powers of 10 and use n to index into this array:

char nthdigit(int x, int n)
{
    static int powersof10[] = {1, 10, 100, 1000, ...};
    return ((x / powersof10[n]) % 10) + '0';
}

As mentioned by others, this is as close as you are going to get to bitwise operations for base 10.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 2
    Second solution is the best of what has been posted speed wise, avoiding strings, floating point, and loops. Best response IMO. – SmacL Oct 15 '08 at 07:09
  • 1
    Note that in the first example above, the n parameter is zero based. nthdigit(1,1) == '0' && nthdigit(1,0) == '1' – eselk May 14 '14 at 02:46
  • @greg what is the significance of " + '0'; " in the code ? – Kanagavelu Sugumar Mar 05 '15 at 09:28
  • 2
    @KanagaveluSugumar That converts the result from an integer to a character. For ASCII, this is equivalent to adding 48 (the character code for `0`). – Greg Hewgill Mar 05 '15 at 16:09
6

Just spent time writing this based on answers here, so thought I would share.

This is based on Brannon's answer, but lets you get more than one digit at a time. In my case I use it to extract parts from a date and time saved in an int where the digits are in yyyymmddhhnnssm_s format.

public static int GetDigits(this int number, int highestDigit, int numDigits)
{
    return (number / (int)Math.Pow(10, highestDigit - numDigits)) % (int)Math.Pow(10, numDigits);
}

I made it an extension, you might not want to, but here is sample usage:

int i = 20010607;
string year = i.GetDigits(8,4).ToString();
string month = i.GetDigits(4,2).ToString();
string day = i.GetDigits(2,2).ToString();

results:

year = 2001

month = 6

day = 7

eselk
  • 6,764
  • 7
  • 60
  • 93
5

Use base-10 math:

class Program
{
    static void Main(string[] args)
    {
        int x = 123456;

        for (int i = 1; i <= 6; i++)
        {
            Console.WriteLine(GetDigit(x, i));
        }
    }

    static int GetDigit(int number, int digit)
    {
        return (number / (int)Math.Pow(10, digit - 1)) % 10;
    }
}

Produces:

6
5
4
3
2
1
Brannon
  • 25,687
  • 5
  • 39
  • 44
4

The reason that it won't work (easily) with bit-wise operations is that the base of the decimal system (10) is not a power of the base of the binary system (2).

If you were coding in base 8, you'd have pow(2, 3) == 8, and could extract each octal digit as a block of three bits.

So you really have to convert to base 10, which is usually done by converting to a string (with toString (Java) or sprintf (C), as the others have shown in their replies).

moritz
  • 12,710
  • 1
  • 41
  • 63
4

This works for unsigned ints up to 451069, as explained here:

def hundreds_digit(u): return mod10(div100(u))

def div100(u): return div10(div10(u))
def mod10(u):  return u - mul10(div10(u))
def mul10(u):  return ((u << 2) + u) << 1

def div10(u):
    Q = ((u >> 1) + u) >> 1  # Q = u*0.11
    Q = ((Q >> 4) + Q)       # Q = u*0.110011
    Q = ((Q >> 8) + Q) >> 3  # Q = u*0.00011001100110011
    return Q

# Alternatively:
#   def div100(u): return (u * 0xa3d7) >> 22
# though that'd only work for 16-bit u values.
# Or you could construct shifts and adds along the lines of div10(),
# but I didn't go to the trouble.

Testing it out:

>>> hundreds_digit(123456)
4
>>> hundreds_digit(123956)
9

I'd be surprised if it's faster, though. Maybe you should reconsider your problem.

Darius Bacon
  • 14,921
  • 5
  • 53
  • 53
  • I commit you do also use the Fixing for the Approximation as refered to on your [link](http://homepage.divms.uiowa.edu/~jones/bcd/divide.html): `if (R >= 10) { R = R - 10; Q = Q + 1; }` Beside that, thank you for your answer, it helped me alot! – Daniel Zemljic Mar 24 '18 at 11:10
1

value = (number % (10^position)) / 10^(position - 1)

Example:

number = 23846

position = 1 -> value = 6

position = 2 -> value = 4

position = 3 -> value = 8

Here is a simple Objective-C utility method to do this:

+ (int)digitAtPosition:(int)pos of:(int)number {

    return (number % ((int)pow(10, pos))) / (int)pow(10, pos - 1);
}
Michael Peterson
  • 10,383
  • 3
  • 54
  • 51
0

You could try a bitwise shift-left (for N-1) and then read the digit at [0], as this could be an assembler approach.

123456 -> 456 -> read first digit

Karsten
  • 14,572
  • 5
  • 30
  • 35
0

Following code will give nth digit from right in a number:

public void getDigit(long n,int k){
    int i=0;
    long r =0;
    while(i<n){
        r=n%10;
        n=n/10;
        i++;
    }
    System.out.println( k + "th digit from right " + r);
 }
Sonal S.
  • 1,444
  • 1
  • 15
  • 31
0

Just for fun, here is the C# extension class for it:

public static class IntExtensions
{
    /// <summary>
    /// Returns the nth digit from an int, 
    /// where 0 is the least significant digit 
    /// and n is the most significant digit.
    /// </summary>
    public static int GetDigit(this int number, int digit)
    {
        for (int i = 0; i < digit; i++)
        {
            number /= 10;
        }
        return number % 10;
    }
}

Usage:

int myNumber = 12345;
int five = myNumber.GetDigit(0);
int four = myNumber.GetDigit(1);
int three = myNumber.GetDigit(2);
int two = myNumber.GetDigit(3);
int one = myNumber.GetDigit(4);
int zero = myNumber.GetDigit(5);
Evorlor
  • 7,263
  • 17
  • 70
  • 141
-1
int returndigit(int n,int d)
{
    d=d-1;
    while(d--)
    {
        n/=10;
    }
    return (n%10);
}
Tunaki
  • 132,869
  • 46
  • 340
  • 423
-1

two digit d1 and d2 will be passed .the program must print the nth Number is the number system that consist only digit with d1 and d2 input format first line contain d1 second line contain d2 third kine contain n d1 is not equal to d2

-2

In C you could do something like the following, where n=0 would indicate the rightmost digit

char nthDigitFromRight(int x,int n)
{
    char str[20];
    sprintf(str,"%020d",x);
    return(str[19 - x]);
}

Change [19-x] to [20-x] if you want n=1 for rightmost digit.

SmacL
  • 22,555
  • 12
  • 95
  • 149
  • Shouldn't that be return(str[19 - x] - '0'); ? And shouldn't the return type be an integer?? – Sundar R Oct 15 '08 at 06:39
  • Not by my reading of the question, third from the right ('4'), '4' to me means a char, if it had said each digit as an integer, or (4) rather than ('4') i would have done it as you suggest. – SmacL Oct 15 '08 at 07:00