Velocity Reviews > my_itoa, any comments?

Peter Nilsson
Guest
Posts: n/a

 10-14-2005
pete wrote:
> Eric Sosman wrote:
>
> > char buff[(CHAR_BIT * sizeof(n) * 10 + 32) / 33 + 1];

>
> char itoa_buff[(size_t)((sizeof(int) * CHAR_BIT - 1) / 3.3) + 3];
> char utoa_buff[(size_t)((sizeof(int) * CHAR_BIT ) / 3.3) + 2];

I understand the +3 over +2 (for the '-'), but what is the point of
the '- 1' in the bitwidth calculation for signed int? Note that the
sign bit contributes additional value as well as the sign.

--
Peter

Peter Nilsson
Guest
Posts: n/a

 10-14-2005
pete wrote:
> Eric Sosman wrote:
>
> > char buff[(CHAR_BIT * sizeof(n) * 10 + 32) / 33 + 1];

>
> char itoa_buff[(size_t)((sizeof(int) * CHAR_BIT - 1) / 3.3) + 3];
> char utoa_buff[(size_t)((sizeof(int) * CHAR_BIT ) / 3.3) + 2];

I understand the +3 over +2 (for the '-'), but what is the point of
the '- 1' in the bitwidth calculation for signed int? Note that the
sign bit contributes additional value as well as the sign.

--
Peter

Michael Mair
Guest
Posts: n/a

 10-14-2005
Old Wolf wrote:
> pete wrote:
>
>>Eric Sosman wrote:
>>
>>
>>> char buff[(CHAR_BIT * sizeof(n) * 10 + 32) / 33 + 1];

>>
>> char itoa_buff[(size_t)((sizeof(int) * CHAR_BIT - 1) / 3.3) + 3];
>> char utoa_buff[(size_t)((sizeof(int) * CHAR_BIT ) / 3.3) + 2];

>
>
> I was going to suggest:
>
> #include <limits.h>
> #define STR(X) #X
> #define STR2(X) STR(X)
>
> char itoa_buff[ sizeof STR2(INT_MAX) ];

Without having looked at the OP's question:
Why leave out room for the sign?

> char utoa_buff[ sizeof STR2(UINT_MAX)];
>
> but it actually doesn't work on my system, because UINT_MAX
> is defined like so:
>
> #define UINT_MAX (2147483647 * 2U + 1U)
>
> so the utoa_buff gets a size of 23! Is there any way to
> make the preprocessor calculate this out?

None that I could think of -- the preprocessor is not required
to perform constant folding. There is conditional compilation
to figure it out (check whether we have certain expected decimal
digits or fall back to your idea) but this is way to ugly.

Uglier yet: What if UINT_MAX is expressed in hex and large
enough to get a shorter string (unlikely, I know)?
Then this is completely off.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.

pete
Guest
Posts: n/a

 10-14-2005
Peter Nilsson wrote:
>
> pete wrote:
> > Eric Sosman wrote:
> >
> > > char buff[(CHAR_BIT * sizeof(n) * 10 + 32) / 33 + 1];

> >
> > char itoa_buff[(size_t)((sizeof(int) * CHAR_BIT - 1) / 3.3) + 3];
> > char utoa_buff[(size_t)((sizeof(int) * CHAR_BIT ) / 3.3) + 2];

>
> I understand the +3 over +2 (for the '-'), but what is the point of
> the '- 1' in the bitwidth calculation for signed int? Note that the
> sign bit contributes additional value as well as the sign.

INT_MAX can have, at most,
(sizeof(int) * CHAR_BIT - 1)
value bits.

In decimal notation,
INT_MIN must have the same number of digits as INT_MAX.

The only way INT_MIN could have more digits than INT_MAX
would be if INT_MIN could be an integer power of ten, but it can't.

INT_MIN must either be odd, or an integral power of two.

--
pete

pete
Guest
Posts: n/a

 10-14-2005
pete wrote:
>
> Peter Nilsson wrote:
> >
> > pete wrote:
> > > Eric Sosman wrote:
> > >
> > > > char buff[(CHAR_BIT * sizeof(n) * 10 + 32) / 33 + 1];
> > >
> > > char itoa_buff[(size_t)((sizeof(int) * CHAR_BIT - 1) / 3.3) + 3];
> > > char utoa_buff[(size_t)((sizeof(int) * CHAR_BIT ) / 3.3) + 2];

> >
> > I understand the +3 over +2 (for the '-'), but what is the point of
> > the '- 1' in the bitwidth calculation for signed int? Note that the
> > sign bit contributes additional value as well as the sign.

>
> INT_MAX can have, at most,
> (sizeof(int) * CHAR_BIT - 1)
> value bits.
>
> In decimal notation,
> INT_MIN must have the same number of digits as INT_MAX.
>
> The only way INT_MIN could have more digits than INT_MAX
> would be if INT_MIN could be an integer power of ten, but it can't.
>
> INT_MIN must either be odd, or an integral power of two.

*Magnitude* of INT_MIN must either be odd, or an integral power of two.

A case where:
(size_t)((sizeof(int) * CHAR_BIT - 1) / 3.3)
== (size_t)((sizeof(int) * CHAR_BIT) / 3.3)

sizeof(int) * CHAR_BIT == 16
char itoa_buff[7] = "-32767"; /* (int)((16 - 1) / 3.3 + 3) == 7 */
char utoa_buff[6] = "65535"; /* (int)( 16 / 3.3 + 2) == 6 */

A case where:
(size_t)((sizeof(int) * CHAR_BIT - 1) / 3.3)
!= (size_t)((sizeof(int) * CHAR_BIT) / 3.3)

sizeof(int) * CHAR_BIT == 20
char itoa_buff[8] = "-524287"; /* (int)((20 - 1) / 3.3 + 3) == 8 */
char utoa_buff[8] = "1048575"; /* (int)( 20 / 3.3 + 2) == 8 */

--
pete

pete
Guest
Posts: n/a

 10-16-2005
Michael Mair wrote:

> Without having looked at the OP's question:
> Why leave out room for the sign?

That was interestingly phrased.

>> Hi,
>>
>> I picked up the itoa example code from K&R and am trying to modify it
>> to as per these conditions:
>> 1) input integer is always +ve

--
pete

Michael Mair
Guest
Posts: n/a

 10-16-2005
pete wrote:
> Michael Mair wrote:
>
>>Without having looked at the OP's question:
>>Why leave out room for the sign?

>
> That was interestingly phrased.

The point I wished to contribute was the other one -- and
the OP's question had not been quoted so I did not see it.

Cheers
Michael
>
>>>Hi,
>>>
>>>I picked up the itoa example code from K&R and am trying to modify it
>>>to as per these conditions:
>>> 1) input integer is always +ve

>
>

--
E-Mail: Mine is an /at/ gmx /dot/ de address.