views:

626

answers:

9

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

A: 

Use a sequence of mod 10 and div 10 operations (whatever the syntax is in C++) to assign the digits one at a time to other variables.

In pseudocode

lsd = number mod 10
number = number div 10
next lsd = number mod 10
number = number div 10

etc...

painful! ... but no strings or character arrays.

pavium
+1  A: 

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

Mark
Nice and general solution. Going through the floating point `floor` function doesn't make much sense, though. Do take a look at Martin's solution, too!
xtofl
Well... I wouldn't actually use floor() but I included that in case the OP was using floats or whatever... just to make it explicit. If he's using int's, then no problem, it's not needed.
Mark
+6  A: 

Something like this:

int* GetDigits(int num, int * array, int len) {
  for (int i = 0; i < len && num != 0; i++) {
    array[i] = num % 10;
    num /= 10;
  }
}

The mod 10's will get you the digits. The div 10s will advance the number.

Steve Rowe
You might not have `len` - it's better to terminate when `num` gets to 0.
Vinay Sajip
Good point. Need len to make sure we don't over-run the array. Added a check for num being 0 though.
Steve Rowe
This can be easily refactored to generate digits for any base. For now it generates digits only for base 10...
SadSido
+3  A: 

The following prints the digits in order of ascending significance (i.e. units, then tens, etc.):

if (n == 0)
    puts("0");
else {
    while (n > 0) {
        int digit = n % 10;
        printf("%d\n", digit);
        n /= 10;
    }
}
Vinay Sajip
if( n == 0 ) no digits are printed.
xtofl
@xtofl: Thanks, corrected.
Vinay Sajip
Do you expect anything when n == 0? I would expect that to be an invalid input thus undefined behavior or an assert.
Martin York
Not worthy of a downvote. This is an illustration, not production-ready code.
Vinay Sajip
And n == 0 *is* a valid input, in my view - the answer is a single digit, '0'.
Vinay Sajip
Another downvote without comment. Sad.
Vinay Sajip
My previous comment was at @xtolf. I think the code was fine.
Martin York
You hardly need printf, BTW. '0' + digit works in ASCII/Unicode. You realize you have simply re-implemented printf %d, right? sprintf %d the original number into a buffer, then reverse the buffer. Put in \n between the digits if you want. Note that sprintf returns the number of characters printed.
Peter Cordes
+8  A: 

You want to some thing like this?

 int n = 0;
    std::cin>>n;

    std::deque<int> digits;
    if(n == 0)
    {
     digits.push_front(0);
     return 0;
    }

    n = abs(n);
    while(n > 0)
    {
     digits.push_front( n % 10);
     n = n /10;
    }
    return 0;
Naveen
+1 for using std containers instead of arrays
Tobias Langner
yes, +1 for std :D
Fu4ny
tiny problem for the number zero, though...
xtofl
@xtofl: Thanks..fixed it :-)
Naveen
I don't exactly understand how this works. Would need to read up on std containers.
chustar
+7  A: 

Since everybody is chiming in without knowing the question.
Here is my attempt at futility:

#include <iostream>

template<int D> int getDigit(int val)       {return getDigit<D-1>(val/10);}
template<>      int getDigit<1>(int val)    {return val % 10;}

int main()
{
    std::cout << getDigit<5>(1234567) << "\n";
}
Martin York
Nice one! And it works for zero, too!
xtofl
Although the runtime complexity is O( sizeof(int)^2 ) when calculating all digits. Hmm.... And how do you know at what digit to start?
xtofl
Technically the runtime complexity is O(1) because the code will not change for different input values. Note Big O notation is a measure of how runtime scales in relation to input arguments.
Martin York
It seems like you pretty much got what i was looking for. Thanks.
chustar
+3  A: 

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

With n digits and using base b you can express any number up to: pow(n,b)-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 decimal (in that case you should know what's the precision of the type you are using).

tunnuz
+1 log using log.
dmeister
+3  A: 

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);
Pavel Shved
A: 

Not as cool as Martin York's answer, but addressing just an arbitrary a problem:

You can print a positive integer greater than zero rather simply with recursion:

#include <stdio.h>
void print(int x)
{
    if (x>0) {
        print(x/10);
        putchar(x%10 + '0');
    }
}

This will print out the least significant digit last.

Matt Curtis