C function for returning number of digits?

Discussion in 'C Programming' started by Luke Wu, Nov 29, 2005.

  1. Luke Wu

    Luke Wu Guest

    Is there a C function that returns the number of digits in an input
    int/long?

    example:

    numdigits(123) returns 3
    numdigits(1232132) returns 7
     
    Luke Wu, Nov 29, 2005
    #1
    1. Advertising

  2. "Luke Wu" <> writes:

    >Is there a C function that returns the number of digits in an input
    >int/long?


    >example:


    >numdigits(123) returns 3
    >numdigits(1232132) returns 7



    Learn about lagarithms, then apply that knowledge to standard C.

    --
    Chris.
     
    Chris McDonald, Nov 29, 2005
    #2
    1. Advertising

  3. Luke Wu

    Luke Wu Guest

    Chris McDonald wrote:
    > "Luke Wu" <> writes:
    >
    > >Is there a C function that returns the number of digits in an input
    > >int/long?

    >
    > >example:

    >
    > >numdigits(123) returns 3
    > >numdigits(1232132) returns 7

    >
    >
    > Learn about lagarithms, then apply that knowledge to standard C.
    >


    Ohh my.... didn't think it would be a two liner.......thank you
    #include<math.h>

    int numdigits(int n)
    return log10(n) + 1;
     
    Luke Wu, Nov 29, 2005
    #3
  4. "Luke Wu" <> writes:


    >Chris McDonald wrote:
    >> "Luke Wu" <> writes:
    >>
    >> >Is there a C function that returns the number of digits in an input
    >> >int/long?

    >>
    >> >example:

    >>
    >> >numdigits(123) returns 3
    >> >numdigits(1232132) returns 7

    >>
    >>
    >> Learn about lagarithms, then apply that knowledge to standard C.
    >>


    >Ohh my.... didn't think it would be a two liner.......thank you
    >#include<math.h>


    >int numdigits(int n)
    > return log10(n) + 1;



    Check its prototype - it's double log10(double x);
    --
    Chris.
     
    Chris McDonald, Nov 29, 2005
    #4
  5. In article <>,
    Luke Wu <> wrote:
    >Is there a C function that returns the number of digits in an input
    >int/long?


    >example:


    >numdigits(123) returns 3
    >numdigits(1232132) returns 7


    There is no standard one, no, but you can write your own.

    But first you will have to define:
    - whether the negative sign counts as a digit or not
    - whether +0 and 0 and -0 have different number of digits

    Be sure to test your routine against LONG_MIN and LONG_MAX
    (which will not necessarily have the same number of digits.)
    And don't just take absolute values: it is common for
    (-LONG_MIN) to exceed LONG_MAX.
    --
    Is there any thing whereof it may be said, See, this is new? It hath
    been already of old time, which was before us. -- Ecclesiastes
     
    Walter Roberson, Nov 29, 2005
    #5
  6. Luke Wu said:

    > Is there a C function that returns the number of digits in an input
    > int/long?
    >
    > example:
    >
    > numdigits(123) returns 3
    > numdigits(1232132) returns 7


    int numdigits(int n)
    {
    int count = 1; /* bound to be at least one digit! */
    while(n != 0)
    {
    n /= 10;
    ++count;
    }
    return count;
    }

    This function ignores signs.

    Note that the logarithm method is a little tighter in source terms, but
    involves a call to log(), which can be expensive, computationally speaking.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Nov 29, 2005
    #6
  7. [attempting to supersede previous (broken) code]

    Luke Wu said:

    > Is there a C function that returns the number of digits in an input
    > int/long?
    >
    > example:
    >
    > numdigits(123) returns 3
    > numdigits(1232132) returns 7


    int numdigits(int n)
    {
    int count = 0;
    do
    {
    ++count;
    n /= 10;
    }
    while(n != 0);
    return count;
    }

    This function ignores signs.

    Note that the logarithm method is a little tighter in source terms, but
    involves a call to log(), which can be expensive, computationally speaking.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Nov 29, 2005
    #7
  8. Luke Wu

    Richard Bos Guest

    Chris McDonald <> wrote:

    > "Luke Wu" <> writes:
    >
    > >Ohh my.... didn't think it would be a two liner.......thank you
    > >#include<math.h>

    >
    > >int numdigits(int n)
    > > return log10(n) + 1;

    >
    > Check its prototype - it's double log10(double x);


    Yes. And with #include <math.h>, the ints and doubles will be
    automatically converted back and forth. Since double is required to
    support at least 10 digits, integers of the size the OP used will be
    converted correctly, without any floating point error. There may still
    be a rounding error _within_ log10(), but that can't be helped, only
    worked around.

    Richard
     
    Richard Bos, Nov 29, 2005
    #8
  9. (Richard Bos) writes:

    >Chris McDonald <> wrote:


    >> "Luke Wu" <> writes:
    >>
    >> >Ohh my.... didn't think it would be a two liner.......thank you
    >> >#include<math.h>

    >>
    >> >int numdigits(int n)
    >> > return log10(n) + 1;

    >>
    >> Check its prototype - it's double log10(double x);

    >Yes. And with #include <math.h>, the ints and doubles will be
    >automatically converted back and forth. Since double is required to
    >support at least 10 digits, integers of the size the OP used will be
    >converted correctly, without any floating point error. There may still
    >be a rounding error _within_ log10(), but that can't be helped, only
    >worked around.


    Thanks; my mistake.
    Perhaps my coding style tends to be too pedantic, as I would have employed
    casts in both places.

    --
    Chris.
     
    Chris McDonald, Nov 29, 2005
    #9
  10. "Luke Wu" <> writes:
    > Chris McDonald wrote:
    >> "Luke Wu" <> writes:
    >>
    >> >Is there a C function that returns the number of digits in an input
    >> >int/long?

    >>
    >> >example:

    >>
    >> >numdigits(123) returns 3
    >> >numdigits(1232132) returns 7

    >>
    >>
    >> Learn about lagarithms, then apply that knowledge to standard C.
    >>

    >
    > Ohh my.... didn't think it would be a two liner.......thank you
    > #include<math.h>
    >
    > int numdigits(int n)
    > return log10(n) + 1;


    I don't think a floating-point solution is best here. A loop using
    integer arithmetic is likely to be faster and more accurate. For that
    matter, a binary search on a lookup table holding powers of 10 is
    likely to be even quicker.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Nov 29, 2005
    #10
  11. Luke Wu

    Richard Bos Guest

    Keith Thompson <> wrote:

    > "Luke Wu" <> writes:
    > > Ohh my.... didn't think it would be a two liner.......thank you
    > > #include<math.h>
    > >
    > > int numdigits(int n)
    > > return log10(n) + 1;

    >
    > I don't think a floating-point solution is best here. A loop using
    > integer arithmetic is likely to be faster and more accurate. For that
    > matter, a binary search on a lookup table holding powers of 10 is
    > likely to be even quicker.


    *g* Never knock the simple solution. You're quite right, of course.

    Richard
     
    Richard Bos, Nov 29, 2005
    #11
  12. Luke Wu

    Ingo Menger Guest

    Richard Bos schrieb:

    > Keith Thompson <> wrote:
    >
    > > "Luke Wu" <> writes:
    > > > Ohh my.... didn't think it would be a two liner.......thank you
    > > > #include<math.h>
    > > >
    > > > int numdigits(int n)
    > > > return log10(n) + 1;

    > >
    > > I don't think a floating-point solution is best here. A loop using
    > > integer arithmetic is likely to be faster and more accurate. For that
    > > matter, a binary search on a lookup table holding powers of 10 is
    > > likely to be even quicker.

    >
    > *g* Never knock the simple solution. You're quite right, of course


    How about:
    int length;
    char digits[100]; /* should be big enough even for 128 bit longs */
    sprintf(digits, "%d", n);
    length = strlen(digits) - (n<0 ? 1 : 0);

    Boxing this code in a function and/or handling special cases (has 0 1
    digit or none?) is left as exercise for the OP.
     
    Ingo Menger, Nov 29, 2005
    #12
  13. Luke Wu

    Jirka Klaue Guest

    Ingo Menger:
    >>> Luke Wu:


    >>>> #include<math.h>
    >>>>
    >>>> int numdigits(int n)
    >>>> return log10(n) + 1;


    > How about:
    > int length;
    > char digits[100]; /* should be big enough even for 128 bit longs */
    > sprintf(digits, "%d", n);
    > length = strlen(digits) - (n<0 ? 1 : 0);


    length = snprintf(0, 0, "%d", n); /* C99 */

    Jirka
     
    Jirka Klaue, Nov 29, 2005
    #13
  14. "Ingo Menger" <> writes:

    > Richard Bos schrieb:
    >
    > > Keith Thompson <> wrote:
    > >
    > > > "Luke Wu" <> writes:
    > > > > Ohh my.... didn't think it would be a two liner.......thank you
    > > > > #include<math.h>
    > > > >
    > > > > int numdigits(int n)
    > > > > return log10(n) + 1;
    > > >
    > > > I don't think a floating-point solution is best here. A loop using
    > > > integer arithmetic is likely to be faster and more accurate. For that
    > > > matter, a binary search on a lookup table holding powers of 10 is
    > > > likely to be even quicker.

    > >
    > > *g* Never knock the simple solution. You're quite right, of course

    >
    > How about:
    > int length;
    > char digits[100]; /* should be big enough even for 128 bit longs */
    > sprintf(digits, "%d", n);
    > length = strlen(digits) - (n<0 ? 1 : 0);


    And how do you fix this when the next version of your compiler ships
    (which use 333 bit longs)?

    A solution using snprintf could work, but io functions are quite complex
    so I'd not be surprised if the log10 was faster. Personally I'd go for
    either a counting loop, or a binary lookup table, depending on how
    critical speed, and time for implementation are.

    /Niklas Norrthon
     
    Niklas Norrthon, Nov 29, 2005
    #14
  15. On Tue, 29 Nov 2005 08:07:37 +0000 (UTC), in comp.lang.c , Chris
    McDonald <> wrote:

    > (Richard Bos) writes:
    >
    >>Chris McDonald <> wrote:

    >
    >>> "Luke Wu" <> writes:
    >>>
    >>> >int numdigits(int n)
    >>> > return log10(n) + 1;
    >>>
    >>> Check its prototype - it's double log10(double x);

    >>Yes. And with #include <math.h>, the ints and doubles will be
    >>automatically converted back and forth.

    >
    >Thanks; my mistake.
    >Perhaps my coding style tends to be too pedantic, as I would have employed
    >casts in both places.


    As a general rule, you shold only use casts when
    a) you actually need one; or
    b) it makes the code less ambiguous

    This could be argued as a (b) since it would show that you really did
    intend to return an int, and would prevent maintenance droids from
    changing it in a tidy-up frenzy. Personally I don't think it does,
    since the function name/purpose is self-documenting. YMMV.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Nov 29, 2005
    #15
  16. In article <>,
    Niklas Norrthon <> wrote:

    >And how do you fix this when the next version of your compiler ships
    >(which use 333 bit longs)?


    >A solution using snprintf could work, but io functions are quite complex
    >so I'd not be surprised if the log10 was faster. Personally I'd go for
    >either a counting loop, or a binary lookup table, depending on how
    >critical speed, and time for implementation are.


    If one is assuming that the next generation compiler might have 333 bit
    longs (and of course the DS9000 has 666 bit longs whenever it feels like
    it ;-) ), then one would need to initialize the binary lookup table
    at runtime. The code to do that without risking overflow (UB) is
    probably not so long, but is likely a bit interesting.
    --
    Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
     
    Walter Roberson, Nov 29, 2005
    #16
  17. Luke Wu

    Ingo Menger Guest

    Niklas Norrthon schrieb:

    > "Ingo Menger" <> writes:
    >
    > > Richard Bos schrieb:
    > >
    > > > Keith Thompson <> wrote:
    > > >
    > > > > "Luke Wu" <> writes:
    > > > > > Ohh my.... didn't think it would be a two liner.......thank you
    > > > > > #include<math.h>
    > > > > >
    > > > > > int numdigits(int n)
    > > > > > return log10(n) + 1;
    > > > >
    > > > > I don't think a floating-point solution is best here. A loop using
    > > > > integer arithmetic is likely to be faster and more accurate. For that
    > > > > matter, a binary search on a lookup table holding powers of 10 is
    > > > > likely to be even quicker.
    > > >
    > > > *g* Never knock the simple solution. You're quite right, of course

    > >
    > > How about:
    > > int length;
    > > char digits[100]; /* should be big enough even for 128 bit longs */
    > > sprintf(digits, "%d", n);
    > > length = strlen(digits) - (n<0 ? 1 : 0);

    >
    > And how do you fix this when the next version of your compiler ships
    > (which use 333 bit longs)?


    I don't. I write the length of the char array as constant expression
    involving sizeof (long) in the first place. For example
    char digits[32 + 4 * sizeof (long)]
    That should do it.
     
    Ingo Menger, Nov 29, 2005
    #17
  18. Luke Wu

    Kevin Handy Guest

    Ingo Menger wrote:
    > Richard Bos schrieb:
    >
    >
    >>Keith Thompson <> wrote:
    >>
    >>
    >>>"Luke Wu" <> writes:
    >>>
    >>>>Ohh my.... didn't think it would be a two liner.......thank you
    >>>>#include<math.h>
    >>>>
    >>>>int numdigits(int n)
    >>>> return log10(n) + 1;
    >>>
    >>>I don't think a floating-point solution is best here. A loop using
    >>>integer arithmetic is likely to be faster and more accurate. For that
    >>>matter, a binary search on a lookup table holding powers of 10 is
    >>>likely to be even quicker.

    >>
    >>*g* Never knock the simple solution. You're quite right, of course

    >
    >
    > How about:
    > int length;
    > char digits[100]; /* should be big enough even for 128 bit longs */
    > sprintf(digits, "%d", n);
    > length = strlen(digits) - (n<0 ? 1 : 0);
    >
    > Boxing this code in a function and/or handling special cases (has 0 1
    > digit or none?) is left as exercise for the OP.
    >


    Is sprintf followed by a strlen actually any faster than log10?
    I'm dubious about it on modern hardware. Plus the additional test
    for sign.

    How about a simple integer loop (destroys n, so make a copy
    if you need to keep it)

    int length;
    while(n)
    {
    length++;
    n /= 10;
    }

    but it still might be slower depending on the availability
    of a hardware log instruction vs. integer division speed.

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Kevin Handy, Nov 29, 2005
    #18
  19. Luke Wu

    Jordan Abel Guest

    On 2005-11-29, Ingo Menger <> wrote:
    >
    > Richard Bos schrieb:
    >
    >> Keith Thompson <> wrote:
    >>
    >> > "Luke Wu" <> writes:
    >> > > Ohh my.... didn't think it would be a two liner.......thank you
    >> > > #include<math.h>
    >> > >
    >> > > int numdigits(int n)
    >> > > return log10(n) + 1;
    >> >
    >> > I don't think a floating-point solution is best here. A loop using
    >> > integer arithmetic is likely to be faster and more accurate. For that
    >> > matter, a binary search on a lookup table holding powers of 10 is
    >> > likely to be even quicker.

    >>
    >> *g* Never knock the simple solution. You're quite right, of course

    >
    > How about:
    > int length;
    > char digits[100]; /* should be big enough even for 128 bit longs */
    > sprintf(digits, "%d", n);
    > length = strlen(digits) - (n<0 ? 1 : 0);


    For c99:

    length = snprintf(0,0,"%d",n)-1;

    > Boxing this code in a function and/or handling special cases (has 0 1
    > digit or none?) is left as exercise for the OP.
     
    Jordan Abel, Nov 29, 2005
    #19
  20. Luke Wu

    Jordan Abel Guest

    On 2005-11-29, Kevin Handy <> wrote:
    > Ingo Menger wrote:
    >> Richard Bos schrieb:
    >>
    >>
    >>>Keith Thompson <> wrote:
    >>>
    >>>
    >>>>"Luke Wu" <> writes:
    >>>>
    >>>>>Ohh my.... didn't think it would be a two liner.......thank you
    >>>>>#include<math.h>
    >>>>>
    >>>>>int numdigits(int n)
    >>>>> return log10(n) + 1;
    >>>>
    >>>>I don't think a floating-point solution is best here. A loop using
    >>>>integer arithmetic is likely to be faster and more accurate. For that
    >>>>matter, a binary search on a lookup table holding powers of 10 is
    >>>>likely to be even quicker.
    >>>
    >>>*g* Never knock the simple solution. You're quite right, of course

    >>
    >>
    >> How about:
    >> int length;
    >> char digits[100]; /* should be big enough even for 128 bit longs */
    >> sprintf(digits, "%d", n);
    >> length = strlen(digits) - (n<0 ? 1 : 0);
    >>
    >> Boxing this code in a function and/or handling special cases (has 0 1
    >> digit or none?) is left as exercise for the OP.
    >>

    >
    > Is sprintf followed by a strlen actually any faster than log10?
    > I'm dubious about it on modern hardware. Plus the additional test
    > for sign.
    >
    > How about a simple integer loop (destroys n, so make a copy
    > if you need to keep it)
    >
    > int length;
    > while(n)
    > {
    > length++;
    > n /= 10;
    > }


    Both log10 and this also fall flat on negative numbers. a negative
    number divided by a positive number is permitted to never result in
    zero; and of course the log of a negative number is non-real. At least
    the sprintf solution returns something that some people _might_ consider
    sensible even in the naivest implementation [counting the minus as a
    digit]
     
    Jordan Abel, Nov 29, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marc Schellens

    Number of digits of float value

    Marc Schellens, Apr 21, 2004, in forum: C++
    Replies:
    4
    Views:
    6,710
    Ivan Vecerina
    Apr 21, 2004
  2. mark
    Replies:
    1
    Views:
    515
    Victor Bazarov
    Jun 14, 2004
  3. bejiz
    Replies:
    12
    Views:
    617
  4. Chris Rebert
    Replies:
    1
    Views:
    389
    Grant Edwards
    Nov 5, 2010
  5. Tim Chase
    Replies:
    2
    Views:
    556
    Tim Chase
    Nov 6, 2010
Loading...

Share This Page