itoa in pure C

C

CBFalconer

pete said:
.... snip ...


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.
 
P

pete

pete said:
Peter Nilsson wrote:

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.

I'm thinking about converting -1.
'0' - i % 10 is '1', so that looks good.

This code is unreachable on my machine,
so all I can do is to think about it.

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;
 
P

pete

pete said:
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

I'm thinking about converting -1.
'0' - i % 10 is '1', so that looks good.


This code is unreachable on my machine,
so all I can do is to think about it.


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++;

 
P

pete

pete said:
/* (a/b)*b + a%b shall equal a */

(-1 / 10 == 0, 0) * 10 + (-1 % 10 == -1, -1) == -1


I can't make , "(a/b)*b + a%b shall equal a "
hold for those numbers, so I think I'm wrong.


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++;
 
P

Peter Nilsson

-1/10 => -0.1, so the integer division can be 0 or -1.
Yes.


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.
 
P

pete

Peter said:
-1/10 => -0.1, so the integer division can be 0 or -1.
Yes.


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".
 
D

Dave Thompson

[pete wrote:]
Can't do it if UINT_MAX == 65535, and INT_MIN == -65536.
#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.net
 
D

Dan Pop

In said:
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
 
D

Dave Thompson

^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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.net
 
D

Dan Pop

In said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top