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
pete wrote: Dan Pop wrote:
.... snip ... 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; } }
Try a simpler method (untested in C).
if (0 > i) sign = '-';
else {
i = -i;
sign = '\0';
}
p = s;
/* Now sign has been recorded, and i is negative */
/* Only the first digit is critical, after that the range */
/* of i will easily be within that of a positive int */
do {
c = i % 10; /* this step requires careful std reading */
/* about modulus of -ve numbers. Check it */
*p++ = c + '0'; /* which may require adding 10 here */
i /= 10;
} while (i);
if (*p++ = sign) *p++ = '\0';
--p;
/* Now reverse the string s through p in place */
while (s < --p) {
c = *s;
*s++ = *p;
*p = c;
}
There may be an evil gotcha in the above, because something about
modulo changed between C89 and C99.
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; } }
--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
pete wrote: Peter Nilsson wrote: What are your thoughts on...?
char *itoa(int i, char *s) { char *p = s; char *q = s;
if (i >= 0) { do { *q++ = '0' + (i % 10); } while (i /= 10); } else if (-1 % 2 < 0) {
This is the part of the code that runs on my machine.
I believe that here, (-1 % 10 == -1) and (-1 / 10 == 0) are true.
*q++ = '-'; p++;
do { *q++ = '0' - i % 10; } while (i /= 10);
I'm thinking about converting -1.
'0' - i % 10 is '1', so that looks good.
} else {
This code is unreachable on my machine,
so all I can do is to think about it.
*q++ = '-'; p++;
do { int d = i % 10; i = i / 10; if (d) { i++; d = 10 - d; } *q++ = '0' + d; }
I'm thinking about converting -1 again.
I think that in the above loop,
(-1 % 10 == 1) and (-1 / 10 == -2) are true.
I see why i++ is there, but I think that the value of
int d = i % 10;
is correct and should not be altered as in d = 10 - d;
while (i); }
for (*q = 0; p < --q; p++) { char c = *p; *p = *q; *q = c; }
return s; }
At first glance, it seems to be efficient and thorough. I'll take a closer look at it.
--
pete
pete wrote: pete wrote: Peter Nilsson wrote: What are your thoughts on...?
char *itoa(int i, char *s) { char *p = s; char *q = s;
if (i >= 0) { do { *q++ = '0' + (i % 10); } while (i /= 10); } else if (-1 % 2 < 0) { This is the part of the code that runs on my machine. I believe that here, (-1 % 10 == -1) and (-1 / 10 == 0) are true.
/* (a/b)*b + a%b shall equal a */
(-1 / 10 == 0, 0) * 10 + (-1 % 10 == -1, -1) == -1 *q++ = '-'; p++;
do { *q++ = '0' - i % 10; } while (i /= 10); I'm thinking about converting -1. '0' - i % 10 is '1', so that looks good. } else { This code is unreachable on my machine, so all I can do is to think about it. *q++ = '-'; p++;
do { int d = i % 10; i = i / 10; if (d) { i++; d = 10 - d; } *q++ = '0' + d; } I'm thinking about converting -1 again. I think that in the above loop, (-1 % 10 == 1) and (-1 / 10 == -2) are true.
I can't make , "(a/b)*b + a%b shall equal a "
hold for those numbers, so I think I'm wrong.
I see why i++ is there, but I think that the value of int d = i % 10; is correct and should not be altered as in d = 10 - d;
Is this what you're using ?
(-1 / 10 == -1) (-1 % 10 == 9)
That would explain
d = 10 - d;
but not
i++; while (i); }
for (*q = 0; p < --q; p++) { char c = *p; *p = *q; *q = c; }
return s; }
At first glance, it seems to be efficient and thorough. I'll take a closer look at it.
--
pete
pete wrote: pete wrote: pete wrote: Peter Nilsson wrote:
> What are your thoughts on...? > > char *itoa(int i, char *s) > { > char *p = s; > char *q = s; > > if (i >= 0) > { > do > { > *q++ = '0' + (i % 10); > } > while (i /= 10); > } > else if (-1 % 2 < 0) > {
This is the part of the code that runs on my machine. I believe that here, (-1 % 10 == -1) and (-1 / 10 == 0) are true.
/* (a/b)*b + a%b shall equal a */
(-1 / 10 == 0, 0) * 10 + (-1 % 10 == -1, -1) == -1
> *q++ = '-'; > p++; > > do > { > *q++ = '0' - i % 10; > } > while (i /= 10);
I'm thinking about converting -1. '0' - i % 10 is '1', so that looks good.
> } > else > {
This code is unreachable on my machine, so all I can do is to think about it.
> *q++ = '-'; > p++; > > do > { > int d = i % 10; > i = i / 10; > if (d) { i++; d = 10 - d; } > *q++ = '0' + d; > }
I'm thinking about converting -1 again. I think that in the above loop, (-1 % 10 == 1) and (-1 / 10 == -2) are true.
I can't make , "(a/b)*b + a%b shall equal a " hold for those numbers, so I think I'm wrong.
I see why i++ is there, but I think that the value of int d = i % 10; is correct and should not be altered as in d = 10 - d;
Is this what you're using ? (-1 / 10 == -1) (-1 % 10 == 9) That would explain d = 10 - d; but not i++;
Actually it does explain i++;
--
pete
"pete" <pf*****@mindsp ring.com> wrote in message
news:40******** ***@mindspring. com... pete wrote: pete wrote:
.... I'm thinking about converting -1 again. I think that in the above loop, (-1 % 10 == 1) and (-1 / 10 == -2) are true.
I can't make , "(a/b)*b + a%b shall equal a " hold for those numbers, so I think I'm wrong.
-1/10 => -0.1, so the integer division can be 0 or -1. I see why i++ is there, but I think that the value of int d = i % 10; is correct and should not be altered as in d = 10 - d;
Is this what you're using ? (-1 / 10 == -1) (-1 % 10 == 9)
Yes.
That would explain d = 10 - d; but not i++;
Actually it does explain i++;
C89 supports no less than 8 different forms of integer division[*]. But I've
only ever seen two: rounding towards zero, and the mathematical non-negative
remainder version.
You can actually test all of the different versions, simply by adjusting the
results of the existing division. [That's how I tested my code; I replaced
the % and / calculations with some function macros.]
[*] there are three possible ways for at least one of two operands to be
negative, and there are two possible division results for each case.
--
Peter
Peter Nilsson wrote: "pete" <pf*****@mindsp ring.com> wrote in message news:40******** ***@mindspring. com... pete wrote: pete wrote: ... > I'm thinking about converting -1 again. > I think that in the above loop, > (-1 % 10 == 1) and (-1 / 10 == -2) are true.
I can't make , "(a/b)*b + a%b shall equal a " hold for those numbers, so I think I'm wrong. -1/10 => -0.1, so the integer division can be 0 or -1. I see why i++ is there, but I think that the value of > int d = i % 10; > is correct and should not be altered as in d = 10 - d;
Is this what you're using ? (-1 / 10 == -1) (-1 % 10 == 9) Yes. That would explain d = 10 - d; but not i++;
Actually it does explain i++;
C89 supports no less than 8 different forms of integer division[*]. But I've only ever seen two: rounding towards zero, and the mathematical non-negative remainder version.
You can actually test all of the different versions, simply by adjusting the results of the existing division. [That's how I tested my code; I replaced the % and / calculations with some function macros.]
[*] there are three possible ways for at least one of two operands to be negative, and there are two possible division results for each case.
You get my vote for
"most efficient library independant itoa alogorithm".
--
pete
On Thu, 29 Jan 2004 19:13:19 -0500 (EST), "Arthur J. O'Dwyer"
<aj*@nospam.and rew.cmu.edu> wrote: On Thu, 29 Jan 2004, Larry Doolittle wrote: [pete wrote:] Can't do it if UINT_MAX == 65535, and INT_MIN == -65536.
<snip> #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. <snip>
Not by definition; preprocessor arithmetic is done in u/long in C89,
and u/intmax_t in C99. But it is still *possible* that the largest
unsigned type cannot handle the full range of signed INT etc., so on
an absolute-maximum-portability quest you still have the problem.
- David.Thompson1 at worldnet.att.ne t
In <vc************ *************** *****@4ax.com> Dave Thompson <da************ *@worldnet.att. net> writes: Not by definition; preprocessor arithmetic is done in u/long in C89, and u/intmax_t in C99. But it is still *possible* that the largest unsigned type cannot handle the full range of signed INT etc.,
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
It's not only possible, it's a *certitude*.
Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
On 6 Feb 2004 19:29:42 GMT, Da*****@cern.ch (Dan Pop) wrote: In <vc************ *************** *****@4ax.com> Dave Thompson <da************ *@worldnet.att. net> writes:
Not by definition; preprocessor arithmetic is done in u/long in C89, and u/intmax_t in C99. But it is still *possible* that the largest unsigned type cannot handle the full range of signed INT etc., ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ It's not only possible, it's a *certitude*.
Sorry, sloppy wording. I meant can't handle the magnitudes of the full
negative range, and in particular of the 2sC most negative value,
which was the issue upthread.
Nit: a thing that is necessarily or always so, like what you marked,
is a "certainty" . "Certitude" is (and "certainty" is *also*) the
property of a person being confident of something.
- David.Thompson1 at worldnet.att.ne t
In <b7************ *************** *****@4ax.com> Dave Thompson <da************ *@worldnet.att. net> writes: On 6 Feb 2004 19:29:42 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <vc************ *************** *****@4ax.com> Dave Thompson <da************ *@worldnet.att. net> writes:
>Not by definition; preprocessor arithmetic is done in u/long in C89, >and u/intmax_t in C99. But it is still *possible* that the largest >unsigned type cannot handle the full range of signed INT etc., ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ It's not only possible, it's a *certitude*. Sorry, sloppy wording. I meant can't handle the magnitudes of the full negative range, and in particular of the 2sC most negative value, which was the issue upthread.
Unsigned types cannot handle any single bit of the negative range, by
definition.
Nit: a thing that is necessarily or always so, like what you marked, is a "certainty" . "Certitude" is (and "certainty" is *also*) the property of a person being confident of something.
Thanks,
Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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.
|
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);
|
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
|
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;
|
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'
| |
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
|
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);
}
|
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 */
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
| |
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...
|
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...
|
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();...
|
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...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |