rahul said:
On Mon, 21 Jul 2008 19:25:12 +0530, Richard Heathfield
<rj*@see.sig.in validwrote:
>Right (or at least, it will be able to, after you fix the typo) - which
is
why I'm at a loss as to why you continue to recommend this approach.
I assumed that the OP wants an array of int to be converted to string. We
don't have anything that tells us maximum number of digits possible in
int data type.
But we do! (We must, however, not forget that "digits" are a representation
issue, not a property of the type itself.)
For example, if we want a base-1 "tally" representation (clumsy, but
doable), then on a system with, say, 19-bit ints, we know that there will
be no more than 2^(19 - 1) = 262144 digits (all 1s!), and perhaps a
leading minus sign.
Considering only positional systems now (and indeed positional systems with
integral number bases >= 2!), we can derive a general formula for the
maximum number of digits an int can store, and arrange it so that, whilst
we might overestimate a little, we will never underestimate (i.e. we adopt
a conservative attitude).
First, we need the maximum number of bits used in an int. We know that an
int has sizeof(int) bytes (including any padding bits, if applicable), and
we know that a byte has CHAR_BIT bits, so our int can't have more than
sizeof(int) * CHAR_BIT bits in it.
This gives us our first expression:
sizeof(int) * CHAR_BIT
Our worst case for positional systems is base Two, because every bit will
require its own position. In base n, we need log2(n) bits per digit, so an
int can represent no more than (sizeof(int)*CH AR_BIT)/log2(n) digits.
Adding one for the - and one for the terminator gives us the
floating-point expression 1 + 1 + (sizeof(int)*CH AR_BIT) / log2(n) where
log2() might look something like this:
double log2(double x)
{
return log(x) / log(2);
}
Not very convenient, is it? We would prefer a constant integer expression,
right? Well, we can have one, if we are prepared to do a little
pre-calculation for bases that we're particularly interested in. For
example, for base Ten, log2(n) is around 3.32193. This means that, given b
bits of data, every 3.32193+ of them needs a separate character in the
output string for a digit, so we need 1+1+((sizeof(in t)*CHAR_BIT)/3.32193)
characters. Conservatively, 1 + 1 + (sizeof(int) * CHAR_BIT) / 3 would do
it, if it weren't for the fact that integer division is so aggressive.
We'd like to round UP to the next size if need be, rather than down, so we
add 2 to the dividend, giving us 1 + 1 + ((sizeof(int) * CHAR_BIT + 2)/3
This is an integer constant expression, so it can be used in C90 array
definitions:
/* define an array long enough to hold a base-ten representation of a
string, including one for the sign and one for the null */
char textrep[1 + 1 + ((sizeof(int) * CHAR_BIT + 2) / 3] = {0};
Here are the divisors you need for various bases:
base divisor
2 1
3-7 2
8-15 3
16-31 4
32-63 5
64-127 6
The pattern is clear. If you're using number bases higher than 127, you are
likely to run into glyph issues unless you're using Unicode or something,
so I've stopped the table there.
--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999