By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,494 Members | 1,079 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,494 IT Pros & Developers. It's quick & easy.

C function for returning number of digits?

P: n/a
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

Nov 29 '05 #1
Share this Question
Share on Google+
27 Replies


P: n/a
"Luke Wu" <Lo***********@gmail.com> 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.
Nov 29 '05 #2

P: n/a

Chris McDonald wrote:
"Luke Wu" <Lo***********@gmail.com> 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;

Nov 29 '05 #3

P: n/a
"Luke Wu" <Lo***********@gmail.com> writes:

Chris McDonald wrote:
"Luke Wu" <Lo***********@gmail.com> 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.
Nov 29 '05 #4

P: n/a
In article <11**********************@z14g2000cwz.googlegroups .com>,
Luke Wu <Lo***********@gmail.com> 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
Nov 29 '05 #5

P: n/a
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)
Nov 29 '05 #6

P: n/a
[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)
Nov 29 '05 #7

P: n/a
Chris McDonald <ch***@csse.uwa.edu.au> wrote:
"Luke Wu" <Lo***********@gmail.com> 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
Nov 29 '05 #8

P: n/a
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Chris McDonald <ch***@csse.uwa.edu.au> wrote:

"Luke Wu" <Lo***********@gmail.com> 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.
Nov 29 '05 #9

P: n/a
"Luke Wu" <Lo***********@gmail.com> writes:
Chris McDonald wrote:
"Luke Wu" <Lo***********@gmail.com> 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) ks***@mib.org <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.
Nov 29 '05 #10

P: n/a
Keith Thompson <ks***@mib.org> wrote:
"Luke Wu" <Lo***********@gmail.com> 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
Nov 29 '05 #11

P: n/a

Richard Bos schrieb:
Keith Thompson <ks***@mib.org> wrote:
"Luke Wu" <Lo***********@gmail.com> 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.

Nov 29 '05 #12

P: n/a
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
Nov 29 '05 #13

P: n/a
On Tue, 29 Nov 2005 08:07:37 +0000 (UTC), in comp.lang.c , Chris
McDonald <ch***@csse.uwa.edu.au> wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Chris McDonald <ch***@csse.uwa.edu.au> wrote:

"Luke Wu" <Lo***********@gmail.com> 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 =----
Nov 29 '05 #14

P: n/a
"Ingo Menger" <qu*********@consultant.com> writes:
Richard Bos schrieb:
Keith Thompson <ks***@mib.org> wrote:
"Luke Wu" <Lo***********@gmail.com> 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
Nov 29 '05 #15

P: n/a
In article <0p************@niklas.ua.dynas.se>,
Niklas Norrthon <do********@invalid.net> 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
Nov 29 '05 #16

P: n/a
Ingo Menger wrote:
Richard Bos schrieb:

Keith Thompson <ks***@mib.org> wrote:

"Luke Wu" <Lo***********@gmail.com> 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 =----
Nov 29 '05 #17

P: n/a

Niklas Norrthon schrieb:
"Ingo Menger" <qu*********@consultant.com> writes:
Richard Bos schrieb:
Keith Thompson <ks***@mib.org> wrote:

> "Luke Wu" <Lo***********@gmail.com> 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.

Nov 29 '05 #18

P: n/a
On 2005-11-29, Ingo Menger <qu*********@consultant.com> wrote:

Richard Bos schrieb:
Keith Thompson <ks***@mib.org> wrote:
> "Luke Wu" <Lo***********@gmail.com> 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.

Nov 29 '05 #19

P: n/a
On 2005-11-29, Kevin Handy <kt*@srv.net> wrote:
Ingo Menger wrote:
Richard Bos schrieb:

Keith Thompson <ks***@mib.org> wrote:
"Luke Wu" <Lo***********@gmail.com> 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]
Nov 29 '05 #20

P: n/a

Jordan Abel wrote:
On 2005-11-29, Ingo Menger <qu*********@consultant.com> wrote:

Richard Bos schrieb:
Keith Thompson <ks***@mib.org> wrote:

> "Luke Wu" <Lo***********@gmail.com> 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;


Why the -1?

[#3] The snprintf function returns the number of characters
that would have been written had n been sufficiently large,
not counting the terminating null character, or a negative
value if an encoding error occurred. Thus, the null-
terminated output has been completely written if and only if
the returned value is nonnegative and less than n.

Return count doesn't include the terminating null. Sanity check on
this
with gcc:

temp(1186)$ cat foo.c
#include <stdio.h>

int main(void)
{
int foo = 10;
size_t len = snprintf(NULL, 0, "%d", foo);
printf("%d has len %lu\n", foo, (unsigned long) len);

return 0;
}
temp(1187)$ gcc -Wall -pedantic foo.c -o foo
temp(1188)$ foo
10 has len 2

-David

Nov 29 '05 #21

P: n/a
In article <11*********************@g47g2000cwa.googlegroups. com>,
Ingo Menger <qu*********@consultant.com> wrote:
Niklas Norrthon schrieb:
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.


pow(2,332)-1 is 100 digits. Your expression 32 + 4 * sizeof (long)
will not work unless sizeof(long) is at least 17 and CHAR_BIT is
at least 20.

You should be allocating about
CHAR_BITS * sizeof long / (log(10)/log(2))
digits... though remember to allow for rounding and the sign.

Getting sufficient precision on (log(10)/log(2)) at compile
time could be tricky, so possibly the easiest would be to round
that down and overeastimate the number of digits, resulting in

CHAR_BIT * sizeof long / 3
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Nov 29 '05 #22

P: n/a

"Jordan Abel" <jm****@purdue.edu> wrote
At least
the sprintf solution returns something that some people _might_ consider
sensible [ number of digits in a number] even in the naivest
implementation [counting
the minus as a digit]

That is something which is hard to answer. Should a negative number assert
fail? Exhibit undefined behaviour? Return a negative number of digits?
Nov 29 '05 #23

P: n/a
"Malcolm" <re*******@btinternet.com> writes:
"Jordan Abel" <jm****@purdue.edu> wrote
At least
the sprintf solution returns something that some people _might_ consider
sensible [ number of digits in a number] even in the naivest
implementation [counting
the minus as a digit]

That is something which is hard to answer. Should a negative number assert
fail? Exhibit undefined behaviour? Return a negative number of digits?


It's easy to answer: just pick one and make it part of the problem
definition.

If the problem definition doesn't cover negative numbers, then either
it's an inadequate definition or you can just assume undefined
behavior.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Nov 29 '05 #24

P: n/a
Malcolm wrote:
"Jordan Abel" <jm****@purdue.edu> wrote
At least
the sprintf solution returns something that some people _might_ consider
sensible [ number of digits in a number] even in the naivest
implementation [counting
the minus as a digit]

That is something which is hard to answer. Should a negative number assert
fail? Exhibit undefined behaviour? Return a negative number of digits?

Eh, no. The original function was declared as taking an int. Hence, it is
capable of processing negative numbers unless explicitly documented to do
otherwise. Hence, it should return the number of digits in the number. The
number of digits in a negative number is equal to the number of digits in
its absolute value. Confused people may have wanted to ask for the number of
characters instead, in which case the sign counts as a "digit", and the
function is poorly named.

What is hard to answer is why people keep insisting on guessing the intended
behavior of a function by its name instead of using a specification.

S.
Nov 29 '05 #25

P: n/a
In article <43***********************@news.xs4all.nl>,
Skarmander <in*****@dontmailme.com> wrote:
Eh, no. The original function was declared as taking an int. Hence, it is
capable of processing negative numbers unless explicitly documented to do
otherwise. Hence, it should return the number of digits in the number. The
number of digits in a negative number is equal to the number of digits in
its absolute value. Confused people may have wanted to ask for the number of
characters instead, in which case the sign counts as a "digit", and the
function is poorly named. What is hard to answer is why people keep insisting on guessing the intended
behavior of a function by its name instead of using a specification.


If you are going to use that kind of semantic logic, then I would
point out that the number of digits in 01234 is not the same as the
number of digits in 1234.

"digits" are not an inherent property of a number: they are a property
of the representation of the number under some given representation
schema. Whether the indication of negative values is to count
as a "digit" or not depends upon the representation schema.

For example, one could chose a representation schema involving octal
digits and with the property that a negative value is indicated by
a leading "9". How many "digits" are there in 9141 in such a
schema ? How many digits in the hex number B27F ?
--
If you lie to the compiler, it will get its revenge. -- Henry Spencer
Nov 29 '05 #26

P: n/a
Walter Roberson wrote:
In article <43***********************@news.xs4all.nl>,
Skarmander <in*****@dontmailme.com> wrote:
Eh, no. The original function was declared as taking an int. Hence, it is
capable of processing negative numbers unless explicitly documented to do
otherwise. Hence, it should return the number of digits in the number. The
number of digits in a negative number is equal to the number of digits in
its absolute value. Confused people may have wanted to ask for the number of
characters instead, in which case the sign counts as a "digit", and the
function is poorly named.
What is hard to answer is why people keep insisting on guessing the intended
behavior of a function by its name instead of using a specification.


If you are going to use that kind of semantic logic, then I would
point out that the number of digits in 01234 is not the same as the
number of digits in 1234.

"digits" are not an inherent property of a number: they are a property
of the representation of the number under some given representation
schema. Whether the indication of negative values is to count
as a "digit" or not depends upon the representation schema.

Oh yes, very well. The number of digits in the smallest decimal
representation of a number. Don't worry, I wouldn't have forgotten that had
I written the specification of the function. (Well, probably the "smallest"
part, because it's obvious that if leading zeros are allowed, anything goes.)
For example, one could chose a representation schema involving octal
digits and with the property that a negative value is indicated by
a leading "9". How many "digits" are there in 9141 in such a
schema ? How many digits in the hex number B27F ?


Three and four, respectively.

I won't deny that a certain amount of fudging and unclarity is always
involved, unless you want to break everything down to, say, the Peano
axioms. Some things are more reasonable than others when left unspecified,
however.

S.
Nov 29 '05 #27

P: n/a
Richard Heathfield wrote:
[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.


Yep. Quite funny for round-down integer division as allowed by
C89... ;-)

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

--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 30 '05 #28

This discussion thread is closed

Replies have been disabled for this discussion.