如何获得具有逐位运算的整数的第N位数?

时间:2008-10-15 06:19:29

标签: numbers bit-manipulation

实施例。 123456,我们希望第三个从右边('4')出来。

实践中的想法是单独访问每个数字(即6 5 4 3 2 1)。

C / C ++ / C#首选。

12 个答案:

答案 0 :(得分:38)

更有效的实现可能是这样的:

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

如果您只需要其中一个数字,这可以节省将所有数字转换为字符串格式的工作量。而且,您不必为转换后的字符串分配空间。

如果速度是一个问题,你可以预先计算10的幂数并使用n来索引到这个数组:

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

正如其他人所提到的,这与你对基数10的按位操作非常接近。

答案 1 :(得分:5)

使用base-10数学:

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;
    }
}

产地:

6
5
4
3
2
1

答案 2 :(得分:5)

只是花时间在这里根据答案写这个,所以我想分享。

这是基于Brannon的答案,但一次可以让你获得多个数字。在我的例子中,我使用它从保存在int中的日期和时间中提取部分,其中数字为yyyymmddhhnnssm_s格式。

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

我把它作为一个扩展,您可能不想这样做,但这里是示例用法:

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

结果:

year = 2001

月= 6

day = 7

答案 3 :(得分:3)

它不能(轻松)使用逐位操作的原因是十进制系统(10)的基数不是二进制系统(2)的基数。

如果您使用基数8进行编码,则需要pow(2, 3) == 8,并且可以将每个八进制数字提取为三位数。

所以你真的必须转换为基数10,这通常是通过转换为字符串(使用toString(Java)或sprintf(C)来完成的,正如其他人在回复中所示)。

答案 4 :(得分:2)

这适用于最多451069的无符号整数,如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.

测试出来:

>>> hundreds_digit(123456)
4
>>> hundreds_digit(123956)
9
但是,如果它更快,我会感到惊讶。也许你应该重新考虑你的问题。

答案 5 :(得分:1)

value =(数字%(10 ^位置))/ 10 ^(位置-1)

示例:

number = 23846

position = 1 - &gt;值= 6

position = 2 - &gt;值= 4

position = 3 - &gt;值= 8

以下是一个简单的Objective-C实用方法:

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

    return (number % ((int)pow(10, pos))) / (int)pow(10, pos - 1);
}

答案 6 :(得分:0)

您可以尝试按位左移(对于N-1)然后读取[0]处的数字,因为这可能是汇编程序。

123456 - &gt; 456 - &gt;读第一个数字

答案 7 :(得分:0)

以下代码将从数字右侧给出第n位数字:

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);
 }

答案 8 :(得分:0)

只是为了好玩,这里是C#扩展类:

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;
    }
}

用法:

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);

答案 9 :(得分:-1)

int returndigit(int n,int d)
{
    d=d-1;
    while(d--)
    {
        n/=10;
    }
    return (n%10);
}

答案 10 :(得分:-1)

两位数字d1和d2将被传递。程序必须打印第n个数字是仅包含数字的数字系统,带有d1和d2 输入格式 第一行包含d1 第二行包含d2 第三个kine包含n d1不等于d2

答案 11 :(得分:-2)

在C中,您可以执行以下操作,其中n = 0表示最右边的数字

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

如果您想要最右边的数字n = 1,请将[19-x]更改为[20-x]。