473,769 Members | 5,787 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

itoa in pure C

I wrote a version of itoa yesterday.

Features:
1 No implementation defined arithmetic. All of the division
and modulus division is done on positive values only.
2 No object is assumed capable of representing the
magnitude of INT_MIN.
3 The string is constructed in place without reversal.
4 No features from standard library are used.

sput_i writes the decimal representation of a nonnegative int value
argument to an array of char.
sput_ip1 writes the representation of one greater than the
argument value, for any nonnegative int value argument, to an
array of char.

/* BEGIN itoa.c */

void itoa(int, char *);
char *sput_i(int, char *);
char *sput_ip1(int, char *);

void itoa(int integer, char *string)
{
if (0 > integer) {
++integer;
*string++ = '-';
*sput_ip1(-integer, string) = '\0';
} else {
*sput_i(integer , string) = '\0';
}
}

char *sput_i(int integer, char *string)
{
if (integer / 10 != 0) {
string = sput_i(integer / 10, string);
}
*string++ = (char)('0' + integer % 10);
return string;
}

char *sput_ip1(int integer, char *string)
{
int digit;

digit = (integer % 10 + 1) % 10;
if (integer / 10 != 0) {
string = (digit == 0 ? sput_ip1 : sput_i)(integer / 10, string);
*string++ = (char)('0' + digit);
} else {
if (digit == 0) {
*string++ = '1';
}
*string++ = (char)('0' + digit);
}
return string;
}

/* END itoa.c */

--
pete
Nov 14 '05
29 20909
In article <sl************ *********@recyc le.lbl.gov>, Larry Doolittle wrote:
am I guaranteed that the absolute value of i can be represented
in x? A literal reading of this standard would suggest not, [chop
Pete replied (using an forged e-mail address, and in a posting
that never showed up on my news server):
Can't do it if UINT_MAX == 65535, and INT_MIN == -65536.

CHAR_BIT == 16
INT_MAX == 65535
sizeof(unsigned ) == 2
sizeof(int) == 2

unsigned isn't guaranteed to be able to represent
the magnitude of INT_MIN.


Try as I might, I can't think of a machine that
could or would set things up like this. Is there
one, or is the standard unnecessarily permissive?

I guess my code should really look like:

#if -(INT_MIN)>UINT_ MAX
#error this computer may be conforming, but it is too strange for this program
#endif
char *local_itoa(int i)
{
unsigned int x = (i>=0) ? (unsigned) i : -(unsigned) i;

- Larry
Nov 14 '05 #11

On Thu, 29 Jan 2004, Larry Doolittle wrote:

[pete wrote:]
Can't do it if UINT_MAX == 65535, and INT_MIN == -65536.

CHAR_BIT == 16
INT_MAX == 65535
sizeof(unsigned ) == 2
sizeof(int) == 2

unsigned isn't guaranteed to be able to represent
the magnitude of INT_MIN.

[I haven't checked Pete's references, but I'll take it as given
for the moment that he's right.]
Try as I might, I can't think of a machine that
could or would set things up like this. Is there
one, or is the standard unnecessarily permissive?
Sounds unnecessarily permissive to me. But if the Standard
allows it, then you can bet the DS9000 implements it. ;-)
I guess my code should really look like:

#if -(INT_MIN)>UINT_ MAX


Huh? On a "normal" two's-complement machine, this would produce
undefined behavior when you tried to negate INT_MIN. "Fixing" the
code to read

#if (0u - INT_MIN) > UINT_MAX

just makes it sillier: the left-hand side evaluates to some unsigned
int, which by definition cannot be greater than UINT_MAX. So I
have no idea how you thought this code could work -- and even less
idea of how to make it compute what you apparently think it's computing.

-Arthur

Nov 14 '05 #12
Arthur J. O'Dwyer wrote:

On Thu, 29 Jan 2004, Larry Doolittle wrote:

[pete wrote:]
> Can't do it if UINT_MAX == 65535, and INT_MIN == -65536.
>
> CHAR_BIT == 16
> INT_MAX == 65535
> sizeof(unsigned ) == 2
> sizeof(int) == 2
Try as I might, I can't think of a machine that
could or would set things up like this. Is there
one, or is the standard unnecessarily permissive?


Looking at this closer, this sounds like 16 pad bits on unsigned,
and 15 pad bits plus 1 sign bit on signed. Implausible, but
maybe not impossible.
Sounds unnecessarily permissive to me. But if the Standard
allows it, then you can bet the DS9000 implements it. ;-)
I guess my code should really look like:

#if -(INT_MIN)>UINT_ MAX
Huh? On a "normal" two's-complement machine, this would produce
undefined behavior when you tried to negate INT_MIN.


I wasn't aware that the preprocessor suffered the same potential
warts as the execution model. I'll have to go read the standard
more carefully.
So I have no idea how you thought this code could work -- and even less
idea of how to make it compute what you apparently think it's computing.


While I would prefer the standard guarantee that -INT_MIN could be
represented as an unsigned int, I should at least be able to detect
a failure of this assumption at compile time. How about

#if -(INT_MIN+1) > (UINT_MAX-1)

?

- Larry
Nov 14 '05 #13
Larry Doolittle wrote:

Arthur J. O'Dwyer wrote:

On Thu, 29 Jan 2004, Larry Doolittle wrote:

[pete wrote:]
> Can't do it if UINT_MAX == 65535, and INT_MIN == -65536.
>
> CHAR_BIT == 16
> INT_MAX == 65535
> sizeof(unsigned ) == 2
> sizeof(int) == 2

Try as I might, I can't think of a machine that
could or would set things up like this. Is there
one, or is the standard unnecessarily permissive?


Looking at this closer, this sounds like 16 pad bits on unsigned,
and 15 pad bits plus 1 sign bit on signed. Implausible, but
maybe not impossible.
Sounds unnecessarily permissive to me. But if the Standard
allows it, then you can bet the DS9000 implements it. ;-)
I guess my code should really look like:

#if -(INT_MIN)>UINT_ MAX


Huh? On a "normal" two's-complement machine, this would produce
undefined behavior when you tried to negate INT_MIN.


I wasn't aware that the preprocessor suffered the same potential
warts as the execution model. I'll have to go read the standard
more carefully.
So I have no idea how you thought this code could work -- and even less
idea of how to make it compute what you apparently think it's computing.


While I would prefer the standard guarantee that -INT_MIN could be
represented as an unsigned int, I should at least be able to detect
a failure of this assumption at compile time. How about

#if -(INT_MIN+1) > (UINT_MAX-1)


bottom line:
The standard doesn't guarantee that there is any integer type
capable of representing the magnitude of INT_MIN.
That's the relevant rule which makes implementing itoa, amusing.

--
pete
Nov 14 '05 #14
In <40**********@m indspring.com> pete <pf*****@mindsp ring.com> writes:
bottom line:
The standard doesn't guarantee that there is any integer type
capable of representing the magnitude of INT_MIN.
That's the relevant rule which makes implementing itoa, amusing.


It's not that amusing: just treat INT_MIN as a special case: set a flag
and handle it as INT_MIN + 1. If the flag is set, increment the least
significant digit of the result. No need to worry about carry propagation
because no power of two has 0 as its least significant digit.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #15
Dan Pop wrote:

In <40**********@m indspring.com> pete <pf*****@mindsp ring.com> writes:
bottom line:
The standard doesn't guarantee that there is any integer type
capable of representing the magnitude of INT_MIN.
That's the relevant rule which makes implementing itoa, amusing.
It's not that amusing:


That might be why I did it without any standard library headers.
It was adapted from put_d(),
which is a functional component of a minprintf() (K&R2, 7.3)
that I'm writing from "first principles", for no important reason.
It uses stdarg.h of course, but only four features from stdio.h:
EOF, FILE, stdout, and putc(c, stream)
just treat INT_MIN as a special case: set a flag
and handle it as INT_MIN + 1. If the flag is set, increment the least
significant digit of the result.
No need to worry about carry propagation
because no power of two has 0 as its least significant digit.


void ito_a(int i, char *s)
{
char c, *p;
int int_min = 0;

p = s;
if (0 > i) {
*p++ = '-';
++s;
if (i == INT_MIN) {
int_min = 1;
i = INT_MAX;
} else {
i = -i;
}
}
do {
*p++ = (char)('0' + i % 10);
i /= 10;
} while (i);
if (int_min) {
++*s;
}
for (*p = '\0'; --p > s; ++s) {
c = *s;
*s = *p;
*p = c;
}
}
Nov 14 '05 #16
pete wrote:

Dan Pop wrote:

In <40**********@m indspring.com>
pete <pf*****@mindsp ring.com> writes:
The standard doesn't guarantee that there is any integer type
capable of representing the magnitude of INT_MIN.
That's the relevant rule which makes implementing itoa, amusing.
It's not that amusing: just treat INT_MIN as a special case: set a flag
and handle it as INT_MIN + 1.


I think you mean, handle (-1 - INT_MAX) as a special case
if (i == INT_MIN) {


void ito_a(int i, char *s)
{
char c, *p;
int flag = 0;

p = s;
if (0 > i) {
*p++ = '-';
++s;
if (i == -1 - INT_MAX) {
flag = 1;
i = INT_MAX;
} else {
i = -i;
}
}
do {
*p++ = (char)('0' + i % 10);
i /= 10;
} while (i);
if (flag) {
++*s;
}
for (*p = '\0'; --p > s; ++s) {
c = *s;
*s = *p;
*p = c;
}
}
Nov 14 '05 #17
"pete" <pf*****@mindsp ring.com> wrote in message
news:40******** ***@mindspring. com...
Dan Pop wrote:

just treat INT_MIN as a special case: set a flag
and handle it as INT_MIN + 1. If the flag is set, increment the least
significant digit of the result.
No need to worry about carry propagation
because no power of two has 0 as its least significant digit.
void ito_a(int i, char *s)
{
char c, *p;
int int_min = 0;

p = s;
if (0 > i) {
*p++ = '-';
++s;
if (i == INT_MIN) {
int_min = 1;
i = INT_MAX;


You're assuming INT_MIN + 1 == INT_MAX.

i = -(INT_MIN + 1);
} else {
i = -i;
}
}
do {
*p++ = (char)('0' + i % 10);
i /= 10;
} while (i);
if (int_min) {
++*s;
}
for (*p = '\0'; --p > s; ++s) {
c = *s;
*s = *p;
*p = c;
}
}


--
Peter
Nov 14 '05 #18
"pete" <pf*****@mindsp ring.com> wrote in message
news:40******** ***@mindspring. com...
pete wrote:

Dan Pop wrote:

In <40**********@m indspring.com>
pete <pf*****@mindsp ring.com> writes: The standard doesn't guarantee that there is any integer type
> capable of representing the magnitude of INT_MIN.
>That's the relevant rule which makes implementing itoa, amusing.

It's not that amusing: just treat INT_MIN as a special case: set a flag
and handle it as INT_MIN + 1.


I think you mean, handle (-1 - INT_MAX) as a special case
if (i == INT_MIN) {


if (i == -1 - INT_MAX) {


No. On implementations where INT_MIN == -INT_MAX, -1-INT_MAX can overflow.

--
Peter
Nov 14 '05 #19
Peter Nilsson wrote:

"pete" <pf*****@mindsp ring.com> wrote in message
news:40******** ***@mindspring. com...
pete wrote:

Dan Pop wrote:
>
> In <40**********@m indspring.com>
> pete <pf*****@mindsp ring.com> writes:

> > The standard doesn't guarantee that there is any integer type
> > capable of representing the magnitude of INT_MIN.
> >That's the relevant rule which makes implementing itoa, amusing.
>
> It's not that amusing:

> just treat INT_MIN as a special case: set a flag
> and handle it as INT_MIN + 1.


I think you mean, handle (-1 - INT_MAX) as a special case
if (i == INT_MIN) {


if (i == -1 - INT_MAX) {


No. On implementations where INT_MIN == -INT_MAX,
-1-INT_MAX can overflow.


Thank you.

void ito_a(int i, char *s)
{
char c, *p;
int flag = 0;

p = s;
if (0 > i) {
*p++ = '-';
++s;
if (-INT_MAX > i) {
flag = 1;
i = INT_MAX;
} else {
i = -i;
}
}
do {
*p++ = (char)('0' + i % 10);
i /= 10;
} while (i);
if (flag) {
++*s;
}
for (*p = '\0'; --p > s; ++s) {
c = *s;
*s = *p;
*p = c;
}
}
Nov 14 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
3707
by: John Lenton | last post by:
Is there any reason python's printf-style formatting is missing the (C99) '%a' specifier? I'm sorry if this has been asked and answered before; I can't find it on google ('%a' is a very awkward thing to look for): -- John Lenton (john@grulic.org.ar) -- Random fortune: Los cementerios están llenos de valientes.
7
12856
by: news.hku.hk | last post by:
Excuse me, i write the following function to add comma for integers but the unix server said: In function `class string comma(int)': implicit declaration of function `int itoa(...)' ________________________________ string comma(int a){ char to_string; string s_a = itoa(a, to_string, 10);
4
14339
by: Moritz Beller | last post by:
Hello! Is there an equivalent to Visual C++'s itoa function in gcc? best regards Moritz Beller -- web http://www.4momo.de mail momo dot beller at t-online dot de gpgkey http://gpg.notlong.com
2
5030
by: Raskolnikow | last post by:
Hi! I have a very simple problem with itoa() or the localtime(...). Sorry, if it is too simple, I don't have a proper example. Please have a look at the comments. struct tm *systime; time_t currentTime; char day; char month;
2
6678
by: Sona | last post by:
Hi, I have a char* that holds an ascii character in its first element (at least I think that's what it holds because when I print it, it prints weird characters). I need to convert this into an integer and so I thought the following might work: char *somevar ... // somevar holds a value in somevar and is null terminated i.e. somevar = '\0'
11
3604
by: rayw | last post by:
I'm pretty new to C, although I did do some years ago now. I've been told that itoa is no longer a standard function, and that the ato... functions - although in the std - are not recommended. So, I was wondering what was wrong with both itoa and atoi etc (and what's replaced them). Many thanks
24
8206
by: Mark | last post by:
hi, all i want is a simple function that takes an int, and returns a char* so i tried char * itoa(int i) { char buff; return _itoa(i,buff,10); }
7
39554
by: silverburgh.meryl | last post by:
Hi, Can you please tell me where I can find itoa()? I try to compile the following example, but I get the following error: .../t.cpp:20:2: warning: no newline at end of file .../t.cpp: In function 'int main()': .../t.cpp:13: error: 'itoa' was not declared in this scope /* itoa example */
0
10210
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9990
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9860
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8869
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7406
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6668
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5297
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5445
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3560
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.