How to get the digits of a number without converting it to a string/ char array?

前端 未结 15 1064
既然无缘
既然无缘 2020-11-27 04:07

How do I get what the digits of a number are in C++ without converting it to strings or character arrays?

相关标签:
15条回答
  • 2020-11-27 04:33

    Years ago, in response to the above questions I would write the following code:

    int i2a_old(int n, char *s)
    {
        char d,*e=s;//init begin pointer
        do{*e++='0'+n%10;}while(n/=10);//extract digits
        *e--=0;//set end of str_number
        int digits=e-s;//calc number of digits
        while(s<e)d=*s,*s++=*e,*e--=d;//reverse digits of the number
        return digits;//return number of digits
    }
    

    I think that the function printf(...) does something like that.

    Now I will write this:

    int i2a_new(int n, char *s)
    {
        int digits=n<100000?n<100?n<10?1:2:n<1000?3:n<10000?4:5:n<10000000?n<1000000?6:7:n<100000000?8:n<1000000000?9:10;
        char *e=&s[digits];//init end pointer
        *e=0;//set end of str_number
        do{*--e='0'+n%10;}while(n/=10);//extract digits
        return digits;//return number of digits
    }
    

    Advantages: lookup table indipendent; C,C++,Java,JavaScript,PHP compatible; get number of digits, min comparisons: 3; get number of digits, max comparisons: 4; fast code; a comparison is very simple and fast: cmp reg, immediate_data --> 1 CPU clock.

    0 讨论(0)
  • 2020-11-27 04:34

    What about floor(log(number))+1?

    With n digits and using base b you can express any number up to pow(b,n)-1. So to get the number of digits of a number x in base b you can use the inverse function of exponentiation: base-b logarithm. To deal with non-integer results you can use the floor()+1 trick.

    PS: This works for integers, not for numbers with decimals (in that case you should know what's the precision of the type you are using).

    0 讨论(0)
  • 2020-11-27 04:35

    First digit (least significant) = num % 10, second digit = floor(num/10)%10, 3rd digit = floor(num/100)%10. etc

    0 讨论(0)
  • 2020-11-27 04:36

    I have seen many answers, but they all forgot to use do {...} while() loop, which is actually the canonical way to solve this problem and handle 0 properly.

    My solution is based on this one by Naveen.

    int n = 0;
    std::cin>>n;
    
    std::deque<int> digits;
    n = abs(n);
    do {
        digits.push_front( n % 10);
        n /= 10;
    } while (n>0);
    
    0 讨论(0)
  • 2020-11-27 04:41

    simple recursion:

    #include <iostream>
    
    // 0-based index pos
    int getDigit (const long number, int pos) 
    {
        return (pos == 0) ? number % 10 : getDigit (number/10, --pos);
    }
    
    int main (void) {
        std::cout << getDigit (1234567, 4) << "\n";    
    }
    
    0 讨论(0)
  • 2020-11-27 04:44

    Those solutions are all recursive or iterative. Might a more direct approach be a little more efficient?

    Left-to-right:

    int getDigit(int from, int index)
    {
       return (from / (int)pow(10, floor(log10(from)) - index)) % 10;
    }
    

    Right-to-left:

    int getDigit(int from, int index)
    {
       return (from / pow(10, index)) % 10;
    }
    
    0 讨论(0)
提交回复
热议问题