How do I get what the digits of a number are in C++ without converting it to strings or character arrays?
-
Do u want to get number of digits or all the digits in that number in separate variables or integer array?vpram86– vpram862009-09-09 05:45:51 +00:00Commented Sep 9, 2009 at 5:45
-
1What do you mean? Do you want to count the number of digits? Do you want to extract the 5th digit from a number?Loki Astari– Loki Astari2009-09-09 05:46:33 +00:00Commented Sep 9, 2009 at 5:46
-
1Number of what type? Is it integer or double?Kirill V. Lyadvinsky– Kirill V. Lyadvinsky2009-09-09 07:24:03 +00:00Commented Sep 9, 2009 at 7:24
-
1I wanted a way to get all the individual digits into something like an array.chustar– chustar2009-09-09 14:22:17 +00:00Commented Sep 9, 2009 at 14:22
15 Answers
The following prints the digits in order of ascending significance (i.e. units, then tens, etc.):
do {
int digit = n % 10;
putchar('0' + digit);
n /= 10;
} while (n > 0);
6 Comments
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).
5 Comments
ceil(log(x)) instead of floor(log(x))+1 as ceil returns wrong values when log(x) % 1 == 0(e.g. when x = 100 you expect to get 3 (using floor+1) instead of 2 (using just ceil).123321 as example. The number of digits is 6. The digits of this number are 1,2,3,3,2 and 1.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";
}
5 Comments
qDebug() << getDigit<0>(32);, I get: fatal error C1202: recursive type or function dependency context too complex with MSVC2015. I'm assuming the template parameter determines the index of the digit?n >= 1 There is no specialization for zero or negative numbersI 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);
Comments
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;
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.
3 Comments
len - it's better to terminate when num gets to 0.Integer version is trivial:
int fiGetDigit(const int n, const int k)
{//Get K-th Digit from a Number (zero-based index)
switch(k)
{
case 0:return n%10;
case 1:return n/10%10;
case 2:return n/100%10;
case 3:return n/1000%10;
case 4:return n/10000%10;
case 5:return n/100000%10;
case 6:return n/1000000%10;
case 7:return n/10000000%10;
case 8:return n/100000000%10;
case 9:return n/1000000000%10;
}
return 0;
}
Comments
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";
}
1 Comment
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;
}
Comments
First digit (least significant) = num % 10, second digit = floor(num/10)%10, 3rd digit = floor(num/100)%10. etc
2 Comments
floor function doesn't make much sense, though. Do take a look at Martin's solution, too!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.
Comments
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.
Comments
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.
1 Comment
intGet all the individual digits into something like an array - two variants:
int i2array_BigEndian(int n, char a[11])
{//storing the most significant digit first
int digits=//obtain the number of digits with 3 or 4 comparisons
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;
a+=digits;//init end pointer
do{*--a=n%10;}while(n/=10);//extract digits
return digits;//return number of digits
}
int i2array_LittleEndian(int n, char a[11])
{//storing the least significant digit first
char *p=&a[0];//init running pointer
do{*p++=n%10;}while(n/=10);//extract digits
return p-a;//return number of digits
}