1

I have a number like this: int num = 36729; and I want to get the number of digits that compose the number (in this case 5 digits).

How can I do this?

pb2q
  • 58,613
  • 19
  • 146
  • 147
Nick
  • 10,309
  • 21
  • 97
  • 201
  • possible duplicate of [count number of digits - which method is most efficient?](http://stackoverflow.com/questions/9721042/count-number-of-digits-which-method-is-most-efficient) – user7116 Jun 04 '12 at 18:42
  • @sixlettervariables It's not so much a duplicate in terms of the intent, but in terms of the content I'd definitely say so, considering the question itself gives the very answers Nick wanted. – JAB Jun 04 '12 at 20:35

9 Answers9

10

Use this formula:

if(num)
  return floor(log10(abs((double) num)) + 1);

return 1;
gliderkite
  • 8,828
  • 6
  • 44
  • 80
  • This also fails for `num == 0` (and again for each `num <=0`) - though I do admire the elegance of using `log`. If one can assume `num > 0` I doubt there is more elegant solution. Any case - this can be fixed easily as a preprocess – amit Jun 04 '12 at 18:45
  • 2
    You got my +1 after this edit. Elegant. Note that for `num < 0` (if possible) you can multiple with -1 before you take log10, (and add 1 if the - sign should also be counted). – amit Jun 04 '12 at 19:05
  • For edge cases where this doesn't work -- if `double` isn't capable of exactly representing every value of `int`, then your input might get rounded prior to the `log10`, and give the wrong answer. Of course a 64 bit IEEE double can represent every value of a 32bit `int` exactly, so that doesn't apply to any normal-looking C implementation. Provided the input is exact, when it's a power of 10 `log10` should (as a QoI issue) give an exact output. But the C standard doesn't say how accurate math ops are, so if it were to give output `1.9999999`-ish for input `100.0`, then again you're in trouble. – Steve Jessop Jun 04 '12 at 20:40
  • I should probably have said "hypothetical edge cases", it's just that double mathematics where it really matters whether the result is slightly out make me panic. In this case `floor` creates an off-by-one error if the result is slightly below the true value, which is pretty much the definition of a highly unstable numerical computation. But it's easy enough to check any given implementation, to make sure the result never is slightly low. – Steve Jessop Jun 04 '12 at 20:54
2
int digits = 0;
while (num > 0) {
  ++digits;
  num = num / 10;
}
Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
  • 4
    Note that it fails for `num == 0` , this case should be handled manually. In fact for all `num <= 0` the answer will be 0.. Of course it is not an issue if one can assume `num > 0` – amit Jun 04 '12 at 18:42
  • amit, good point. You can handle 0 and negative numbers before this snippet (negative numbers also depends on if the `-` char is considered a "digit"). – Emil Vikström Jun 04 '12 at 18:45
  • Yeap, never said it is not doable, just have to be handled manually :) – amit Jun 04 '12 at 18:46
  • @amit 0 is the correct answer for `n == 0`. You wouldn't say `00050` has 5 digits, it has 2. Likewise `0` has no digits. – Paul Jun 04 '12 at 19:44
  • @PaulP.R.O.: I disagree for the specific case of 0, but I guess this is definition dependent. – amit Jun 04 '12 at 19:53
  • Since logN(0) is undefined, I see no reason why the "number of digits in zero" should be considered meaningful. – wberry Jun 04 '12 at 20:37
1
int unsigned_digit_count(unsigned val) {
    int count = 0;
    do {
        count++;
        val /= 10;
    } while (val);
    return count;
}

int digit_count(int val) {
    if (val < 0) {
        return 1+unsigned_digit_count(-val); // extra digit for the '-'
    } else {
        return unsigned_digit_count(val);
    }
}
nategoose
  • 12,054
  • 27
  • 42
1
  1. The number of digits of an integer n in any base is trivially obtained by dividing until you're done:
unsigned int number_of_digits = 0;
do {
    ++number_of_digits; 
    n /= base;
} while (n);
  1. Not necessarily the most efficient, but one of the shortest and most readable using C++: std::to_string(num).length()

  2. And there is a much better way to do it:

#include<cmath>
...
int size = trunc(log10(num)) + 1
...
Ala
  • 11
  • 2
0

Hint: use the / and the % operators.

ouah
  • 142,963
  • 15
  • 272
  • 331
0
int findcount(int num) 
{ 
    int count = 0; 
    if(num != 0){
      while(num) { 
          num /= 10; 
          count ++; 
      } 
      return count ; 
    }
    else
      return 1;
} 
Jainendra
  • 24,713
  • 30
  • 122
  • 169
  • If `num` is `0` the number of digits is `1`. – gliderkite Jun 04 '12 at 19:08
  • As explained by Amit [here](http://stackoverflow.com/questions/10886413/get-number-of-digits-of-a-number/10886429#comment14189154_10886429) the condiion for `num ==0` will be handelled manually. – Jainendra Jun 04 '12 at 19:18
  • Souldn't `0` have 0 digits. You wouldn't say `00050` has 5 digits, it has 2. – Paul Jun 04 '12 at 19:43
  • @PaulP.R.O. `00050` and `50` have the same value, but `0` and ` ` do not. – JAB Jun 04 '12 at 19:56
  • @JAB Don't they? `0` is just a mathematical representation of `nil`. It's the absence of quantity. I think you are thinking of `0` as a string rather than the actual value it represents. – Paul Jun 04 '12 at 20:02
  • @JAB You can also verify this on wolfram alpha: http://www.wolframalpha.com/input/?i=how+many+digits+are+in+the+number+0 – Paul Jun 04 '12 at 20:11
  • @PaulP.R.O. A value has no intrinsic number of digits until you give it a representation, meaning digit-counting is intrinsically a string-related operation. hexadecimal `FF`, octal `377`, and decimal `255` are all the same value, but the hex representation is two digits long compared to the three digits for octal and decimal. – JAB Jun 04 '12 at 20:16
  • @PaulP.R.O. That result disagrees with itself; it says there are zero digits in 0, then goes on to say that the base-ten digit count for that value is one 0. – JAB Jun 04 '12 at 20:19
  • @JAB Yes, that does disagree with itself, but if you add the specific base into the query you get `0` as well: http://www.wolframalpha.com/input/?i=how+many+digits+are+in+the+number+0+base+10. The number of digits for an arbitrary integer is base specific, but `0` is 0 digits in all bases. – Paul Jun 04 '12 at 20:24
  • @PaulP.R.O. Very well, I give in. It seems funny for a value with parity to have no digits, but oh well. – JAB Jun 04 '12 at 20:26
  • I think the fact that Wolfram Alpha directly contradicts itself is telling. (a) it doesn't know what it's talking about, because (b) it doesn't really matter. There's no important universal definition of "how many digits are there in a number?" or "how many 0-digits are there in a number?", so the fact that Wolfram happens to use different definitions for each just tells you that when you're writing this code, you can treat the edge case of 0 however best suits you. – Steve Jessop Jun 04 '12 at 20:50
0

For any input other than 0, compute the base-10 logarithm of the absolute value of the input, take the floor of that result and add 1:

int dig;
...
if (input == 0)
  dig = 1;
else
  dig = (int) floor(log10(abs((double) input))) + 1;

0 is a special case and has to be handled separately.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Inefficient, but strangely elegant...

#include <stdio.h>
#include <string.h>

int main(void)
{
    // code to get value
    char str[50];
    sprintf(str, "%d", value);

    printf("The %d has %d digits.\n", value, strlen(str));

    return 0;
}
JAB
  • 20,783
  • 6
  • 71
  • 80
  • Provided that you have a C99-compliant `snprintf` (i.e. not Microsoft's `_snprintf`), its return value is the number of characters required. So you could save a separate call to `strlen` and do it in one line: `return snprintf(0, 0, "%d", value);`. – Steve Jessop Jun 04 '12 at 20:42
  • @SteveJessop Ah, that's a nice tip. – JAB Jun 04 '12 at 20:46
-1

Can't you do this ?

    int num = 36729;
    num.ToString().Length
crassr3cords
  • 280
  • 1
  • 7