COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### integer overflow in atoi

• Email
• Follow

```I want to implement atoi function which converts string to an integer.
So I did this :

int atoi(char str[])
{
int i, num;
for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
num = num * 10 + str[i] - '0' ;
return num;
}

Here I wnat to know is there any way to tell user if num goes out of
range of int ?
I mean we can't check num after overflow as it will be UB so is there
a way to check if str[] contains large integer ?
```
 0
Reply hppymittal (23) 1/21/2010 4:16:21 PM

See related articles to this posting

```On Jan 21, 11:16=A0am, happy <hppymit...@yahoo.com> wrote:
> I want to implement atoi function which converts string to an integer.
> So I did this :
>
> int atoi(char str[])
> {
> =A0 int i, num;
> =A0 for( num =3D 0, i =3D 0 ; isdigit(str[i]) ; i++)
> =A0 =A0 =A0 num =3D num * 10 + str[i] - '0' ;
> =A0 return num;
>
> }
>
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?
> I mean we can't check num after overflow as it will be UB so is there
> a way to check if str[] contains large integer ?

The usual way would be to check to ensure that num < (num * 10 +
value).  I don't think that's 100% portable but for all practical
purposes it's just fine.

Tom
```
 0
Reply Tom 1/21/2010 4:32:27 PM

```On 1/21/2010 11:32 AM, Tom St Denis wrote:
> On Jan 21, 11:16 am, happy<hppymit...@yahoo.com>  wrote:
>> I want to implement atoi function which converts string to an integer.
>> So I did this :
>>
>> int atoi(char str[])
>> {
>>    int i, num;
>>    for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>>        num = num * 10 + str[i] - '0' ;
>>    return num;
>>
>> }
>>
>> Here I wnat to know is there any way to tell user if num goes out of
>> range of int ?
>> I mean we can't check num after overflow as it will be UB so is there
>> a way to check if str[] contains large integer ?
>
> The usual way would be to check to ensure that num<  (num * 10 +
> value).  I don't think that's 100% portable but for all practical
> purposes it's just fine.
>
> Tom

Except that that doesn't work.  Take for example (assuming 32-bit ints)
num = 0x40000000.  Then num*10 = 0x80000000 after the overflow, which is
still bigger than num.

The best I can come up with is to compare num with ((num * 10 + value) -
value)/10.  If they are equal then the inner paranthetical expression
didn't overflow.  If not then it did.  To be explicit:

int atoi(char str[])
{
int i, num, numtemp;
for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
{
numtemp = num
num = num * 10 + str[i] - '0' ;
if(numtemp != ((num - str[i]) + '0')/10)
{
/* Overflow */
}
}
return num;
}

--
Dan Giaimo
```
 0
Reply news 1/21/2010 4:49:10 PM

```happy <hppymittal@yahoo.com> wrote:
> I want to implement atoi function which converts string to an integer.
> So I did this :

> int atoi(char str[])
> {
>   int i, num;
>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>       num = num * 10 + str[i] - '0' ;
>   return num;
> }

> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?
> I mean we can't check num after overflow as it will be UB so is there
> a way to check if str[] contains large integer ?

You could check if num is larger than INT_MAX / 10 before you
multiply it by 10. If that isn't the case and num has been mul-
tiplied by 10 you then have to check if INT_MAX minus the new
digit is not smaller than 'num'. Another way would be to do a
string comparison on 'str' (but only the part that contains
numbers!) to a stringified version of INT_MAX, obtained defi-
ning the macros

#define _STRFY( x ) #x
#define STRFY( x ) _STRFY( x )

and using something like

if (    strlen( str ) > strlen( STRFY( INT_MAX ) )
|| strcmp( str, STRFY( INT_MAX ) ) > 0 )
puts( "overflow" );

Reporting an overflow back to the user could be done in the same
way strtol() does it, i.e. passing back INT_MAX and setting errno
to ERANGE.
Regards, Jens
--
\   Jens Thoms Toerring  ___      jt@toerring.de
\__________________________      http://toerring.de
```
 0
Reply jt 1/21/2010 4:52:21 PM

```On 1/21/2010 11:49 AM, news.telesweet.net wrote:
> On 1/21/2010 11:32 AM, Tom St Denis wrote:
>> On Jan 21, 11:16 am, happy<hppymit...@yahoo.com> wrote:
>>> I want to implement atoi function which converts string to an integer.
>>> So I did this :
>>>
>>> int atoi(char str[])
>>> {
>>> int i, num;
>>> for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>>> num = num * 10 + str[i] - '0' ;
>>> return num;
>>>
>>> }
>>>
>>> Here I wnat to know is there any way to tell user if num goes out of
>>> range of int ?
>>> I mean we can't check num after overflow as it will be UB so is there
>>> a way to check if str[] contains large integer ?
>>
>> The usual way would be to check to ensure that num< (num * 10 +
>> value). I don't think that's 100% portable but for all practical
>> purposes it's just fine.
>>
>> Tom
>
> Except that that doesn't work. Take for example (assuming 32-bit ints)
> num = 0x40000000. Then num*10 = 0x80000000 after the overflow, which is
> still bigger than num.
>
> The best I can come up with is to compare num with ((num * 10 + value) -
> value)/10. If they are equal then the inner paranthetical expression
> didn't overflow. If not then it did. To be explicit:
>
> int atoi(char str[])
> {
> int i, num, numtemp;
> for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
> {
> numtemp = num
> num = num * 10 + str[i] - '0' ;
> if(numtemp != ((num - str[i]) + '0')/10)
> {
> /* Overflow */
> }
> }
> return num;
> }
>
> --
> Dan Giaimo

I must be exhausted.  The example above only works for unsigned ints.
For signed ints try num = 0x20000000.  Then num*10 = 0x40000000 after
the overflow and the same considerations apply.

--
Dan G
```
 0
Reply news 1/21/2010 4:56:05 PM

```"Tom St Denis" <tom@iahu.ca> wrote in message
news:0a169ba1-0bb4-436a-acd7-8034567aface@k35g2000yqb.googlegroups.com...
> On Jan 21, 11:16 am, happy <hppymit...@yahoo.com> wrote:
> > I want to implement atoi function which converts string to an integer.
> > So I did this :
> >
> > int atoi(char str[])
> > {
> > int i, num;
> > for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
> > num = num * 10 + str[i] - '0' ;
> > return num;
> >
> > }
> >
> > Here I wnat to know is there any way to tell user if num goes out of
> > range of int ?
> > I mean we can't check num after overflow as it will be UB so is there
> > a way to check if str[] contains large integer ?
>
> The usual way would be to check to ensure that num < (num * 10 +
> value).  I don't think that's 100% portable but for all practical
> purposes it's just fine.

Yes, it's just fine, other than the fact that it doesn't work.  For example,
assume a platform with 32 bit two's complement int's, and which does
overflow handling by discarding the high order bits.  Then, on the last
iteration of computing:

atoi( "5000000000" )

num will initially be 500000000, and then num*10+value will be 705032704;
because 705032704>500000000, overflow will not be detected.

Instead, in this particular case, I would suggest making the test:

if (num > INT_MAX/10 || (num == INT_MAX/10 && value > INT_MAX%10))
handle_overflow();

(I'd also suggest making num an unsigned int, but that's not strictly
speaking necesssary)

--
poncho

```
 0
Reply Scott 1/21/2010 5:00:59 PM

```"Tom St Denis" <tom@iahu.ca> wrote in message
news:0a169ba1-0bb4-436a-acd7-8034567aface@k35g2000yqb.googlegroups.com...
> On Jan 21, 11:16 am, happy <hppymit...@yahoo.com> wrote:
> > I want to implement atoi function which converts string to an integer.
> > So I did this :
> >
> > int atoi(char str[])
> > {
> > int i, num;
> > for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
> > num = num * 10 + str[i] - '0' ;
> > return num;
> >
> > }
> >
> > Here I wnat to know is there any way to tell user if num goes out of
> > range of int ?
> > I mean we can't check num after overflow as it will be UB so is there
> > a way to check if str[] contains large integer ?
>
> The usual way would be to check to ensure that num < (num * 10 +
> value).  I don't think that's 100% portable but for all practical
> purposes it's just fine.

Yes, it's just fine, other than the fact that it doesn't work.  For example,
assume a platform with 32 bit two's complement int's, and which does
overflow handling by discarding the high order bits.  Then, on the last
iteration of computing:

atoi( "5000000000" )

num will initially be 500000000, and then num*10+value will be 705032704;
because 705032704>500000000, overflow will not be detected.

Instead, in this particular case, I would suggest making the test:

if (num > INT_MAX/10 || (num == INT_MAX/10 && value > INT_MAX%10))
handle_overflow();

(I'd also suggest making num an unsigned int, but that's not strictly
speaking necesssary)

--
poncho

```
 0
Reply Scott 1/21/2010 5:00:59 PM

```On Jan 21, 11:49=A0am, "news.telesweet.net" <dgia...@gmail.com> wrote:
> On 1/21/2010 11:32 AM, Tom St Denis wrote:
>
>
>
> > On Jan 21, 11:16 am, happy<hppymit...@yahoo.com> =A0wrote:
> >> I want to implement atoi function which converts string to an integer.
> >> So I did this :
>
> >> int atoi(char str[])
> >> {
> >> =A0 =A0int i, num;
> >> =A0 =A0for( num =3D 0, i =3D 0 ; isdigit(str[i]) ; i++)
> >> =A0 =A0 =A0 =A0num =3D num * 10 + str[i] - '0' ;
> >> =A0 =A0return num;
>
> >> }
>
> >> Here I wnat to know is there any way to tell user if num goes out of
> >> range of int ?
> >> I mean we can't check num after overflow as it will be UB so is there
> >> a way to check if str[] contains large integer ?
>
> > The usual way would be to check to ensure that num< =A0(num * 10 +
> > value). =A0I don't think that's 100% portable but for all practical
> > purposes it's just fine.
>
> > Tom
>
> Except that that doesn't work. =A0Take for example (assuming 32-bit ints)
> num =3D 0x40000000. =A0Then num*10 =3D 0x80000000 after the overflow, whi=
ch is
> still bigger than num.

Except it does work...

tstdenis@photon:~\$ cat test.c
#include<stdio.h>
#include<limits.h>
int main (void)
{
int a;
a =3D INT_MAX/10;
printf("%d %d %d\n", a < (a * 10), a, a*10);
++a;
printf("%d %d %d\n", a < (a * 10), a, a*10);
return 0;
}
tstdenis@photon:~\$ ./test
1 214748364 2147483640
0 214748365 -2147483646

The second case fails since a is not less than a*10 which means an
overflow occurred.

Tom
```
 0
Reply Tom 1/21/2010 5:08:37 PM

```On Jan 21, 12:00=A0pm, "Scott Fluhrer" <sfluh...@ix.netcom.com> wrote:
> "Tom St Denis" <t...@iahu.ca> wrote in messagenews:0a169ba1-0bb4-436a-acd=
7-8034567aface@k35g2000yqb.googlegroups.com...
>
>
>
> > On Jan 21, 11:16 am, happy <hppymit...@yahoo.com> wrote:
> > > I want to implement atoi function which converts string to an integer=
..
> > > So I did this :
>
> > > int atoi(char str[])
> > > {
> > > int i, num;
> > > for( num =3D 0, i =3D 0 ; isdigit(str[i]) ; i++)
> > > num =3D num * 10 + str[i] - '0' ;
> > > return num;
>
> > > }
>
> > > Here I wnat to know is there any way to tell user if num goes out of
> > > range of int ?
> > > I mean we can't check num after overflow as it will be UB so is there
> > > a way to check if str[] contains large integer ?
>
> > The usual way would be to check to ensure that num < (num * 10 +
> > value). =A0I don't think that's 100% portable but for all practical
> > purposes it's just fine.
>
> Yes, it's just fine, other than the fact that it doesn't work. =A0For exa=
mple,
> assume a platform with 32 bit two's complement int's, and which does
> overflow handling by discarding the high order bits. =A0Then, on the last
> iteration of computing:
>
> =A0 =A0atoi( "5000000000" )
>
> num will initially be 500000000, and then num*10+value will be 705032704;
> because 705032704>500000000, overflow will not be detected.

Am I missing something here?  neither of  0x1DCD6500 or 0x2A05F200 are
too big for a 32-bit int.  Why would there be an overflow?

tstdenis@photon:~\$ cat test.c
#include<stdio.h>
#include<limits.h>
int main (void)
{
int a;
a =3D 500000000; INT_MAX/10;
printf("%d %d %d\n", a < (a * 10), a, a*10);
++a;
printf("%d %d %d\n", a < (a * 10), a, a*10);
return 0;
}
tstdenis@photon:~\$ ./test
1 500000000 705032704
1 500000001 705032714

Which is exactly what I would expect happen...  They're both in range
and return true for the test a < (a*10 + v).

Tom
```
 0
Reply Tom 1/21/2010 5:15:49 PM

```On Jan 21, 12:15=A0pm, Tom St Denis <t...@iahu.ca> wrote:
> On Jan 21, 12:00=A0pm, "Scott Fluhrer" <sfluh...@ix.netcom.com> wrote:
>
>
>
> > "Tom St Denis" <t...@iahu.ca> wrote in messagenews:0a169ba1-0bb4-436a-a=
cd7-8034567aface@k35g2000yqb.googlegroups.com...
>
> > > On Jan 21, 11:16 am, happy <hppymit...@yahoo.com> wrote:
> > > > I want to implement atoi function which converts string to an integ=
er.
> > > > So I did this :
>
> > > > int atoi(char str[])
> > > > {
> > > > int i, num;
> > > > for( num =3D 0, i =3D 0 ; isdigit(str[i]) ; i++)
> > > > num =3D num * 10 + str[i] - '0' ;
> > > > return num;
>
> > > > }
>
> > > > Here I wnat to know is there any way to tell user if num goes out o=
f
> > > > range of int ?
> > > > I mean we can't check num after overflow as it will be UB so is the=
re
> > > > a way to check if str[] contains large integer ?
>
> > > The usual way would be to check to ensure that num < (num * 10 +
> > > value). =A0I don't think that's 100% portable but for all practical
> > > purposes it's just fine.
>
> > Yes, it's just fine, other than the fact that it doesn't work. =A0For e=
xample,
> > assume a platform with 32 bit two's complement int's, and which does
> > overflow handling by discarding the high order bits. =A0Then, on the la=
st
> > iteration of computing:
>
> > =A0 =A0atoi( "5000000000" )
>
> > num will initially be 500000000, and then num*10+value will be 70503270=
4;
> > because 705032704>500000000, overflow will not be detected.
>
> Am I missing something here? =A0neither of =A00x1DCD6500 or 0x2A05F200 ar=
e
> too big for a 32-bit int. =A0Why would there be an overflow?
>
> tstdenis@photon:~\$ cat test.c
> #include<stdio.h>
> #include<limits.h>
> int main (void)
> {
> int a;
> a =3D 500000000; INT_MAX/10;
> printf("%d %d %d\n", a < (a * 10), a, a*10);
> ++a;
> printf("%d %d %d\n", a < (a * 10), a, a*10);
> return 0;}
>
> tstdenis@photon:~\$ ./test
> 1 500000000 705032704
> 1 500000001 705032714
>
> Which is exactly what I would expect happen... =A0They're both in range
> and return true for the test a < (a*10 + v).

Here is the algorithm "not working" ... (ignore the use of sprintf, I
wasn't thinking and/or I'm busy at work ya ... that's it)

tstdenis@photon:~\$ cat test.c
#include<stdio.h>
#include<limits.h>

int t_atoi(char *s)
{
int tmp, num =3D 0;
while (*s) {
tmp =3D num; num =3D num * 10 + *s++ - '0';
if (tmp > num) { printf("OVERFLOW\n"); }
}
return num;
}

int main(void)
{
char buf[64];
sprintf(buf, "%lu", (unsigned long)INT_MAX);
printf("%d\n", t_atoi(buf));
sprintf(buf, "%lu", (unsigned long)INT_MAX + 1);
printf("%d\n", t_atoi(buf));
return 0;
}

tstdenis@photon:~\$ ./test
2147483647
OVERFLOW
-2147483648

Tom
```
 0
Reply Tom 1/21/2010 5:22:23 PM

```happy wrote:
> I want to implement atoi function which converts string to an integer.
> So I did this :
>
> int atoi(char str[])
> {
>   int i, num;
>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>       num = num * 10 + str[i] - '0' ;
>   return num;
> }
>
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?

The maximum value num can legally have is INT_MAX.

The maximum value str[i] can have (within the loop) is '9', so str[i] -
'0' is at most 9. Therefore, the result of num * 10 can't exceed INT_MAX
- 9, so num mustn't exceed (INT_MAX - 9) / 10.

#include <limits.h>
int my_atoi(char str[])
{
int i = 0;
int num = 0;
int max = (INT_MAX - 9) / 10;
while(isdigit(str[i] && num < max)
{
num = num * 10 + str[i++] - '0';
}
return num;
}

Question: having discovered that overflow would occur, what will you do?
Alert the user? Or simply stop processing digits, documenting that the
function processes as many characters as it legally can (as shown above)?

Another question: have you considered the possibility of a sign? e.g.
atoi("-42");

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
Reply Richard 1/21/2010 5:30:34 PM

```Tom St Denis wrote:
<snip>
>>>> On Jan 21, 11:16 am, happy <hppymit...@yahoo.com> wrote:

<snip>

>>>>> Here I wnat to know is there any way to tell user if num goes out of
>>>>> range of int ?
>>>>> I mean we can't check num after overflow as it will be UB so is there
>>>>> a way to check if str[] contains large integer ?

<snip>

>
> int t_atoi(char *s)
> {
>    int tmp, num = 0;
>    while (*s) {
>      tmp = num; num = num * 10 + *s++ - '0';
>      if (tmp > num) { printf("OVERFLOW\n"); }

By the time you've detected overflow, you're too late - the behaviour is
undefined. The OP (see above) clearly knows this already.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
Reply Richard 1/21/2010 5:32:22 PM

```Richard Heathfield wrote:
) The maximum value num can legally have is INT_MAX.
)
) The maximum value str[i] can have (within the loop) is '9', so str[i] -
) '0' is at most 9. Therefore, the result of num * 10 can't exceed INT_MAX
) - 9, so num mustn't exceed (INT_MAX - 9) / 10.

And what if a user enters a number that's (almost) exactly INT_MAX ?
You're trading simplicity for a slightly shorter range.

Perhaps you could precalculate two sentinels, and if you're inbetween
do the exact calculation.

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
```
 0
Reply Willem 1/21/2010 5:37:07 PM

```On Jan 21, 12:15=A0pm, Tom St Denis <t...@iahu.ca> wrote:
> On Jan 21, 12:00=A0pm, "Scott Fluhrer" <sfluh...@ix.netcom.com> wrote:
>
>
>
> > "Tom St Denis" <t...@iahu.ca> wrote in messagenews:0a169ba1-0bb4-436a-a=
cd7-8034567aface@k35g2000yqb.googlegroups.com...
>
> > > On Jan 21, 11:16 am, happy <hppymit...@yahoo.com> wrote:
> > > > I want to implement atoi function which converts string to an integ=
er.
> > > > So I did this :
>
> > > > int atoi(char str[])
> > > > {
> > > > int i, num;
> > > > for( num =3D 0, i =3D 0 ; isdigit(str[i]) ; i++)
> > > > num =3D num * 10 + str[i] - '0' ;
> > > > return num;
>
> > > > }
>
> > > > Here I wnat to know is there any way to tell user if num goes out o=
f
> > > > range of int ?
> > > > I mean we can't check num after overflow as it will be UB so is the=
re
> > > > a way to check if str[] contains large integer ?
>
> > > The usual way would be to check to ensure that num < (num * 10 +
> > > value). =A0I don't think that's 100% portable but for all practical
> > > purposes it's just fine.
>
> > Yes, it's just fine, other than the fact that it doesn't work. =A0For e=
xample,
> > assume a platform with 32 bit two's complement int's, and which does
> > overflow handling by discarding the high order bits. =A0Then, on the la=
st
> > iteration of computing:
>
> > =A0 =A0atoi( "5000000000" )
>
> > num will initially be 500000000, and then num*10+value will be 70503270=
4;
> > because 705032704>500000000, overflow will not be detected.
>
> Am I missing something here? =A0neither of =A00x1DCD6500 or 0x2A05F200 ar=
e
> too big for a 32-bit int. =A0Why would there be an overflow?
>
> tstdenis@photon:~\$ cat test.c
> #include<stdio.h>
> #include<limits.h>
> int main (void)
> {
> int a;
> a =3D 500000000; INT_MAX/10;
> printf("%d %d %d\n", a < (a * 10), a, a*10);
> ++a;
> printf("%d %d %d\n", a < (a * 10), a, a*10);
> return 0;}
>
> tstdenis@photon:~\$ ./test
> 1 500000000 705032704
> 1 500000001 705032714
>
> Which is exactly what I would expect happen... =A0They're both in range
> and return true for the test a < (a*10 + v).
>
> Tom

Look very carefully at what _you_ just wrote:

For a =3D 500000000:

(1) a < (a * 10) evaluated to 1

(2) a evaluated to 500000000

(3) a * 10 evaluated to 705032714

Last time I checked 500000000 * 10 =3D 5000000000, not 705032714.
Therefore
you overflowed.  However, your test (see line (1)) would imply that no
overflow occurred.  I don't think I can make this any simpler.

--
Dan Giaimo
```
 0
Reply dgiaimo 1/21/2010 5:42:33 PM

```Willem wrote:
> Richard Heathfield wrote:
> ) The maximum value num can legally have is INT_MAX.
> )
> ) The maximum value str[i] can have (within the loop) is '9', so str[i] -
> ) '0' is at most 9. Therefore, the result of num * 10 can't exceed INT_MAX
> ) - 9, so num mustn't exceed (INT_MAX - 9) / 10.
>
> And what if a user enters a number that's (almost) exactly INT_MAX ?

I'm trading simplicity for a slightly shorter range.

> You're trading simplicity for a slightly shorter range.

Right. :-)

> Perhaps you could precalculate two sentinels, and if you're inbetween
> do the exact calculation.

Or just use strtol, as \$deity intended.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
Reply Richard 1/21/2010 5:43:36 PM

```"Tom St Denis" <tom@iahu.ca> wrote in message
news:dfa958f6-d0b8-45e8-a24f-10f42dcda174@g23g2000vbl.googlegroups.com...
On Jan 21, 12:00 pm, "Scott Fluhrer" <sfluh...@ix.netcom.com> wrote:
> > Yes, it's just fine, other than the fact that it doesn't work. For
> > example,
> > assume a platform with 32 bit two's complement int's, and which does
> > overflow handling by discarding the high order bits. Then, on the last
> > iteration of computing:
> >
> > atoi( "5000000000" )
> >
> > num will initially be 500000000, and then num*10+value will be
> > 705032704;
> > because 705032704>500000000, overflow will not be detected.
>
> Am I missing something here?  neither of  0x1DCD6500 or 0x2A05F200 are
> too big for a 32-bit int.  Why would there be an overflow?

0x1DCD6500 == 5000000000 fits into a 32-bit int, however 10*5000000000+0 ==
0x12A05F200 does not.  The CPU handles the overflow by discarding the high
order bits, giving 0x2A05F200 == 705032704.  So, in this specific case, an
overflow happens that is not detected by your test.

> tstdenis@photon:~\$ cat test.c
> #include<stdio.h>
> #include<limits.h>
> int main (void)
> {
> int a;
> a = 500000000; INT_MAX/10;
> printf("%d %d %d\n", a < (a * 10), a, a*10);
> ++a;
> printf("%d %d %d\n", a < (a * 10), a, a*10);
> return 0;
> }
> tstdenis@photon:~\$ ./test
> 1 500000000 705032704
> 1 500000001 705032714
>
> Which is exactly what I would expect happen...  They're both in range
> and return true for the test a < (a*10 + v).

Are you assuming that "a < (a*10 + v)" indicates an overflow?  That's also
true in the nonoverflow case (unless a=v=0)

--
poncho

```
 0
Reply Scott 1/21/2010 5:44:47 PM

```On Jan 21, 12:44=A0pm, "Scott Fluhrer" <sfluh...@ix.netcom.com> wrote:
> 0x1DCD6500 =3D=3D 5000000000 fits into a 32-bit int, however 10*500000000=
0+0 =3D=3D
> 0x12A05F200 does not. =A0The CPU handles the overflow by discarding the h=
igh
> order bits, giving 0x2A05F200 =3D=3D 705032704. =A0So, in this specific c=
ase, an
> overflow happens that is not detected by your test.

The real problem [other than I shouldn't be posting to usenet over
lunch] is gcalc betrayed me and truncated the result.

:-)

Tom
```
 0
Reply Tom 1/21/2010 5:51:07 PM

```The result according to the C Standard:

1. Ignore leading white space, convert the optional sign ('+' or '-')
plus all digits to a number.
2. If the result does not fit into the range from LONG_MIN to LONG_MAX
then replace it with LONG_MIN or LONG_MAX.
3. Convert the result to type int.

So it's a lot easier to implement long atol (const char* str) first,
and make atoi

int atoi(const char* str)
{
return (int) atol (str);
}

In the implementation of atol, first ignore white space characters
using isspace (). Process a plus or minus character. Then process the
digits. When each digit is processed, there are three cases:

1. Result so far is less than LONG_MAX / 10: Times 10, plus next
digit.
2. Result so far is greater than LONG_MAX / 10, or there is another
digit: Return LONG_MAX or LONG_MIN, depending on the sign.
3. Result so far is equal to LONG_MAX / 10: Check whether the digit
will cause on overflow. The maximum value is (LONG_MAX % 10) if the
sign is positive, or (10 - LONG_MIN) % 10 if the sign is negative.
Return LONG_MAX or LONG_MIN if the next digit is too large. Otherwise,
return the value, being careful that an input of LONG_MIN will be
returned without any stupid overflows.
```
 0
Reply christian 1/21/2010 6:41:30 PM

```happy wrote:
> I want to implement atoi function which converts string to an integer.
> So I did this :
>
> int atoi(char str[])
> {
>   int i, num;
>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>       num = num * 10 + str[i] - '0' ;
>   return num;
> }
>
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?
> I mean we can't check num after overflow as it will be UB so is there
> a way to check if str[] contains large integer ?

If you really are implementing a function
that does exactly what atoi does,
then you don't have to check if num goes out of range.
The standard library function (atoi), doesn't do that.

--
pete
```
 0
Reply pete 1/21/2010 6:52:39 PM

```happy wrote:
> I want to implement atoi function which converts string to an integer.
> So I did this :
>
> int atoi(char str[])
> {
>   int i, num;
>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>       num = num * 10 + str[i] - '0' ;
>   return num;
> }
>
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?
> I mean we can't check num after overflow as it will be UB so is there
> a way to check if str[] contains large integer ?

If you want to report an error, don't implement atoi (which doesn't
indicate failure), implement strtol, which does.

--
Ian Collins
```
 0
Reply Ian 1/21/2010 7:07:04 PM

```christian.bau wrote:
> The result according to the C Standard:
>
> 1. Ignore leading white space, convert the optional sign ('+' or '-')
> plus all digits to a number.
> 2. If the result does not fit into the range from LONG_MIN to LONG_MAX
> then replace it with LONG_MIN or LONG_MAX.

You just made that up.

ISO/IEC 9899:1999 (E)

7.20.1 Numeric conversion functions

1 The functions atof, atoi, atol, and atoll
need not affect the value of the integer
expression errno on an error.
If the value of the result cannot be represented,
the behavior is undefined.

> 3. Convert the result to type int.
>
> So it's a lot easier to implement long atol (const char* str) first,
> and make atoi
>
> int atoi(const char* str)
> {
>   return (int) atol (str);
> }

--
pete
```
 0
Reply pete 1/21/2010 7:17:42 PM

```jt@toerring.de (Jens Thoms Toerring) writes:
> happy <hppymittal@yahoo.com> wrote:
>> I want to implement atoi function which converts string to an integer.
>> So I did this :
>
>> int atoi(char str[])
>> {
>>   int i, num;
>>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>>       num = num * 10 + str[i] - '0' ;
>>   return num;
>> }
>
>> Here I wnat to know is there any way to tell user if num goes out of
>> range of int ?
>> I mean we can't check num after overflow as it will be UB so is there
>> a way to check if str[] contains large integer ?
>
> You could check if num is larger than INT_MAX / 10 before you
> multiply it by 10. If that isn't the case and num has been mul-
> tiplied by 10 you then have to check if INT_MAX minus the new
> digit is not smaller than 'num'. Another way would be to do a
> string comparison on 'str' (but only the part that contains
> numbers!) to a stringified version of INT_MAX, obtained defi-
> ning the macros
>
> #define _STRFY( x ) #x
> #define STRFY( x ) _STRFY( x )
>
> and using something like
>
> if (    strlen( str ) > strlen( STRFY( INT_MAX ) )
>      || strcmp( str, STRFY( INT_MAX ) ) > 0 )
>     puts( "overflow" );
>
> Reporting an overflow back to the user could be done in the same
> way strtol() does it, i.e. passing back INT_MAX and setting errno
> to ERANGE.

The string comparison trick only works if INT_MAX is defined as a
decimal constant.  It merely has to be a constant expression of type
int.  For example, <limits.h> could plausibly have:

#define INT_MAX 0x7fffffff

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
```
 0
Reply Keith 1/21/2010 8:37:13 PM

```happy <hppymittal@yahoo.com> writes:
> I want to implement atoi function which converts string to an integer.
> So I did this :
>
> int atoi(char str[])
> {
>   int i, num;
>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>       num = num * 10 + str[i] - '0' ;
>   return num;
> }
>
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?
> I mean we can't check num after overflow as it will be UB so is there
> a way to check if str[] contains large integer ?

Apart from the other comments you've gotten, the identifier "atoi"
is always reserved for use as an external identifier.  If you write
your own function with that name (unless you declare it static),
the behavior is undefined.  For example, a call might quietly call
the system's atoi() function rather than yours.

If you're writing your own atoi() function as an exercise, pick a
different name (unless you're implementing the C standard library).

strtol(), also in the standard, is much better in terms of error
handling, though it's a little complicated to use.  A friendlier
wrapper around strtol() might be a nice thing to have.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
```
 0
Reply Keith 1/21/2010 8:42:23 PM

```Keith Thompson <kst-u@mib.org> wrote:
> jt@toerring.de (Jens Thoms Toerring) writes:
> > ... Another way would be to do a
> > string comparison on 'str' (but only the part that contains
> > numbers!) to a stringified version of INT_MAX, obtained defi-
> > ning the macros
> >
> > #define _STRFY( x ) #x
> > #define STRFY( x ) _STRFY( x )
> >
> > and using something like
> >
> > if (    strlen( str ) > strlen( STRFY( INT_MAX ) )
> >      || strcmp( str, STRFY( INT_MAX ) ) > 0 )
> >     puts( "overflow" );

> The string comparison trick only works if INT_MAX is defined as a
> decimal constant.  It merely has to be a constant expression of type
> int.  For example, <limits.h> could plausibly have:

>     #define INT_MAX 0x7fffffff

Right, what a pity;-) But with a bit more of effort I guess it
can still be made to work:

char im[ ( CHAR_BIT * sizeof( int ) ) / 3 + 1 ];
sprintf( im, "%d\n", INT_MAX );
if ( strlen( str ) > strlen( im ) || strcmp( str, im ) > 0 )
puts( "overflow" );
Regards, Jens
--
\   Jens Thoms Toerring  ___      jt@toerring.de
\__________________________      http://toerring.de
```
 0
Reply jt 1/21/2010 9:23:58 PM

```pete <pfiland@mindspring.com> writes:
> christian.bau wrote:
>> The result according to the C Standard:
>>
>> 1. Ignore leading white space, convert the optional sign ('+' or '-')
>> plus all digits to a number.
>> 2. If the result does not fit into the range from LONG_MIN to LONG_MAX
>> then replace it with LONG_MIN or LONG_MAX.
>
> You just made that up.

No he didn't. He plucked it mostly from the standard. OK,
from the bit of the standard that describes the behaviour of
strtol rather than ato[il].

Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
```
 0
Reply Phil 1/21/2010 9:37:33 PM

```happy a �crit :
> I want to implement atoi function which converts string to an integer.
> So I did this :
>
> int atoi(char str[])
> {
>   int i, num;
>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>       num = num * 10 + str[i] - '0' ;
>   return num;
> }
>
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?
> I mean we can't check num after overflow as it will be UB so is there
> a way to check if str[] contains large integer ?

Use a double for comparing num*10 against INT_MAX:

double d = num;
if (d*10 > INT_MAX)
etc

jacob
```
 0
Reply jacob 1/21/2010 10:22:28 PM

```happy <hppymittal@yahoo.com> writes:

> int atoi(char str[])
> {
>   int i, num;
>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>       num = num * 10 + str[i] - '0' ;
>   return num;
> }
>
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?

if (num > INT_MAX / 10) {
...handle overflow...
}
--
"Some people *are* arrogant, and others read the FAQ."
--Chris Dollin
```
 0
Reply Ben 1/21/2010 10:43:20 PM

```jacob navia <jacob@nospam.org> writes:
> happy a écrit :
>> I want to implement atoi function which converts string to an integer.
>> So I did this :
>>
>> int atoi(char str[])
>> {
>>   int i, num;
>>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>>       num = num * 10 + str[i] - '0' ;
>>   return num;
>> }
>>
>> Here I wnat to know is there any way to tell user if num goes out of
>> range of int ?
>> I mean we can't check num after overflow as it will be UB so is there
>> a way to check if str[] contains large integer ?
>
> Use a double for comparing num*10 against INT_MAX:
>
> double d = num;
> if (d*10 > INT_MAX)
>    etc

That can fail if double has fewer value bits than int does (e.g., if
int and double are both 64 bits).

Aside from that, I'd write the above as:

if (num * 10.0 > INT_MAX) /* ... */

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
```
 0
Reply Keith 1/21/2010 10:59:48 PM

```"Jens Thoms Toerring" <jt@toerring.de> wrote in message
news:7rruveFe2aU1@mid.uni-berlin.de...
> Keith Thompson <kst-u@mib.org> wrote:
>> jt@toerring.de (Jens Thoms Toerring) writes:
>> > ... Another way would be to do a
>> > string comparison on 'str' (but only the part that contains
>> > numbers!) to a stringified version of INT_MAX, obtained defi-
>> > ning the macros
>> >
>> > #define _STRFY( x ) #x
>> > #define STRFY( x ) _STRFY( x )
>> >
>> > and using something like
>> >
>> > if (    strlen( str ) > strlen( STRFY( INT_MAX ) )
>> >      || strcmp( str, STRFY( INT_MAX ) ) > 0 )
>> >     puts( "overflow" );
>
>> The string comparison trick only works if INT_MAX is defined as a
>> decimal constant.  It merely has to be a constant expression of type
>> int.  For example, <limits.h> could plausibly have:
>
>>     #define INT_MAX 0x7fffffff
>
> Right, what a pity;-) But with a bit more of effort I guess it
> can still be made to work:
>
>  char im[ ( CHAR_BIT * sizeof( int ) ) / 3 + 1 ];
>  sprintf( im, "%d\n", INT_MAX );
>  if ( strlen( str ) > strlen( im ) || strcmp( str, im ) > 0 )
>      puts( "overflow" );

I use a similar technique in a real application. But I only do the strcmp()
test when both strings are the same length, otherwise it goes wrong I think.

--
bartc

```
 0
Reply bartc 1/21/2010 11:05:00 PM

```"Ben Pfaff" <blp@cs.stanford.edu> wrote in message
news:871vhjrsdg.fsf@blp.benpfaff.org...
> happy <hppymittal@yahoo.com> writes:
>
>> int atoi(char str[])
>> {
>>   int i, num;
>>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>>       num = num * 10 + str[i] - '0' ;
>>   return num;
>> }
>>
>> Here I wnat to know is there any way to tell user if num goes out of
>> range of int ?
>
> if (num > INT_MAX / 10) {
>    ...handle overflow...

Let's say INT_MAX is 2147483647 for example. So you're doing:

if (num>214748364) ... overflow.

However this might not detect overflows for inputs of "2147483648" and
"2147483649" (assuming you're doing the test with at least one more digit in
hand).

--
Bartc

```
 0
Reply bartc 1/21/2010 11:11:46 PM

```"bartc" <bartc@freeuk.com> writes:

> "Ben Pfaff" <blp@cs.stanford.edu> wrote in message
> news:871vhjrsdg.fsf@blp.benpfaff.org...
>> happy <hppymittal@yahoo.com> writes:
>>
>>> int atoi(char str[])
>>> {
>>>   int i, num;
>>>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>>>       num = num * 10 + str[i] - '0' ;
>>>   return num;
>>> }
>>>
>>> Here I wnat to know is there any way to tell user if num goes out of
>>> range of int ?
>>
>> if (num > INT_MAX / 10) {
>>    ...handle overflow...
>
> Let's say INT_MAX is 2147483647 for example. So you're doing:
>
> if (num>214748364) ... overflow.
>
> However this might not detect overflows for inputs of "2147483648" and
> "2147483649" (assuming you're doing the test with at least one more digit in
> hand).

Telling whether you can add a digit between 0 and 9 is the easy
and obvious part :-)
--
"I don't have C&V for that handy, but I've got Dan Pop."
--E. Gibbons
```
 0
Reply Ben 1/21/2010 11:14:56 PM

```On 1/21/2010 6:05 PM, bartc wrote:
> "Jens Thoms Toerring" <jt@toerring.de> wrote
>> [...]
>> char im[ ( CHAR_BIT * sizeof( int ) ) / 3 + 1 ];
>> sprintf( im, "%d\n", INT_MAX );
>> if ( strlen( str ) > strlen( im ) || strcmp( str, im ) > 0 )
>> puts( "overflow" );
>
> I use a similar technique in a real application. But I only do the
> strcmp() test when both strings are the same length, otherwise it goes
> wrong I think.

So if im[] holds "2147483647" and str is "11111111111111111"
you'll conclude that all's well?

--
Eric Sosman
esosman@ieee-dot-org.invalid
```
 0
Reply Eric 1/21/2010 11:46:50 PM

```"Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
news:hjap17\$5r7\$1@news.eternal-september.org...
> On 1/21/2010 6:05 PM, bartc wrote:
>> "Jens Thoms Toerring" <jt@toerring.de> wrote
>>> [...]
>>> char im[ ( CHAR_BIT * sizeof( int ) ) / 3 + 1 ];
>>> sprintf( im, "%d\n", INT_MAX );
>>> if ( strlen( str ) > strlen( im ) || strcmp( str, im ) > 0 )
>>> puts( "overflow" );
>>
>> I use a similar technique in a real application. But I only do the
>> strcmp() test when both strings are the same length, otherwise it goes
>> wrong I think.
>
>     So if im[] holds "2147483647" and str is "11111111111111111"
> you'll conclude that all's well?

I didn't say I'd leave out the strlen(str)>strlen(im) part. Only that I
would then test for strlen(str)==strlen(im) before calling strcmp().

--
Bartc

```
 0
Reply bartc 1/21/2010 11:58:58 PM

```Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
> On 1/21/2010 6:05 PM, bartc wrote:
> > "Jens Thoms Toerring" <jt@toerring.de> wrote
> >> [...]
> >> char im[ ( CHAR_BIT * sizeof( int ) ) / 3 + 1 ];
> >> sprintf( im, "%d\n", INT_MAX );
> >> if ( strlen( str ) > strlen( im ) || strcmp( str, im ) > 0 )
> >> puts( "overflow" );
> >
> > I use a similar technique in a real application. But I only do the
> > strcmp() test when both strings are the same length, otherwise it goes
> > wrong I think.

>      So if im[] holds "2147483647" and str is "11111111111111111"
> you'll conclude that all's well?

I guess that bartc meant that when the length isn't equal you
actually don't have to do anymore checks since then the question
is already answered (but then, as I just realized, there is ano-
ther point that needs to be taken care about: what about strings
that start with one or more '0'?). Just the concern about the string
being shorter than a "stringified" version of INT_MAX is something I
don't get since strcmp() will return -1 if 'str' is shorter than 'im'.

Regards, Jens
--
\   Jens Thoms Toerring  ___      jt@toerring.de
\__________________________      http://toerring.de
```
 0
Reply jt 1/22/2010 12:01:56 AM

```Phil Carmody wrote:
> pete <pfiland@mindspring.com> writes:
>> christian.bau wrote:
>>> The result according to the C Standard:
>>>
>>> 1. Ignore leading white space, convert the optional sign ('+' or '-')
>>> plus all digits to a number.
>>> 2. If the result does not fit into the range from LONG_MIN to LONG_MAX
>>> then replace it with LONG_MIN or LONG_MAX.
>> You just made that up.
>
> No he didn't. He plucked it mostly from the standard. OK,
> from the bit of the standard that describes the behaviour of
> strtol rather than ato[il].

Yes, the bit of the standard that describes
the behavior of strtol which is different from atoi.

--
pete
```
 0
Reply pete 1/22/2010 12:08:02 AM

```"Jens Thoms Toerring" <jt@toerring.de> wrote in message
news:7rs87kFt7qU1@mid.uni-berlin.de...
> Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
>> On 1/21/2010 6:05 PM, bartc wrote:
>> > "Jens Thoms Toerring" <jt@toerring.de> wrote
>> >> [...]
>> >> char im[ ( CHAR_BIT * sizeof( int ) ) / 3 + 1 ];
>> >> sprintf( im, "%d\n", INT_MAX );
>> >> if ( strlen( str ) > strlen( im ) || strcmp( str, im ) > 0 )
>> >> puts( "overflow" );
>> >
>> > I use a similar technique in a real application. But I only do the
>> > strcmp() test when both strings are the same length, otherwise it goes
>> > wrong I think.
>
>>      So if im[] holds "2147483647" and str is "11111111111111111"
>> you'll conclude that all's well?
>
> I guess that bartc meant that when the length isn't equal you
> actually don't have to do anymore checks since then the question
> is already answered (but then, as I just realized, there is ano-
> ther point that needs to be taken care about: what about strings
> that start with one or more '0'?). Just the concern about the string
> being shorter than a "stringified" version of INT_MAX is something I
> don't get since strcmp() will return -1 if 'str' is shorter than 'im'.

My strcmp() behaves differently from yours then:

printf("%d\n", strcmp("9","214748647"));

outputs 1 on my machine.

--
Bartc

```
 0
Reply bartc 1/22/2010 12:08:09 AM

```On Jan 22, 12:08=A0am, pete <pfil...@mindspring.com> wrote:
> Yes, the bit of the standard that describes
> the behavior of strtol which is different from atoi.

Since this is about _implementing_ a library function or a function
that is compatible with the definition of a library function, anything
in the standard that says where the use of that library function
invokes undefined behaviour can be ignored.

If the standard says "Except in the case of errors, where behaviour is
undefined, the behaviour is like this..."
then we can implement "The behaviour is like this..."

```
 0
Reply christian 1/22/2010 12:19:31 AM

```pete <pfiland@mindspring.com> writes:
> Phil Carmody wrote:
>> pete <pfiland@mindspring.com> writes:
>>> christian.bau wrote:
>>>> The result according to the C Standard:
>>>>
>>>> 1. Ignore leading white space, convert the optional sign ('+' or '-')
>>>> plus all digits to a number.
>>>> 2. If the result does not fit into the range from LONG_MIN to LONG_MAX
>>>> then replace it with LONG_MIN or LONG_MAX.
>>> You just made that up.
>>
>> No he didn't. He plucked it mostly from the standard. OK, from the
>> bit of the standard that describes the behaviour of strtol rather
>> than ato[il].
>
> Yes, the bit of the standard that describes
> the behavior of strtol which is different from atoi.

Erm, I think that's what I said. Is you a bit fick?

--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
```
 0
Reply Phil 1/22/2010 6:50:50 PM

```On Jan 21, 10:16=A0am, happy <hppymit...@yahoo.com> wrote:
> [...]
> Here I wnat to know is there any way to tell user if num goes out of
> range of int ?
> [...]

Richard Heathfield wrote:
The maximum value str[i] can have (within the loop) is '9', so
str[i] - '0' is at most 9. Therefore, the result of num * 10 can't
exceed INT_MAX - 9, so num mustn't exceed (INT_MAX - 9) / 10.

Willem wrote:
And what if a user enters a number that's (almost) exactly INT_MAX?
You're trading simplicity for a slightly shorter range.

Jens wrote:
You could check if num is larger than INT_MAX/10 before you multiply
it by 10. If that isn't the case and num has been multiplied by 10
you then have to check if INT_MAX minus the new digit is not smaller
than 'num'.
----------------------------------------------------------------------

Putting the ideas above together, and noting ((INT_MAX/10)-1) gives
the same result as (INT_MAX-9)/10, you can get the complete range
with:

If num <=3D ((INT_MAX/10)-1) there can't be an overflow. For 32 bit
signed int this is 214,748,363 and the maximum result is 2,147,483,639

Else if num =3D (INT_MAX/10) =3D 214,748,364 and (str[i]-'0') < 8 you are
OK - this gives numbers from 2,147,483,640 to 2,147,483,647

Else overflow is certain if you continue.
----------------------------------------------------------------------

Note:
As long as the bitlength of the integer is a power of 2, the magic
number 8 in the 'Else if' line works for signed integers:
2^7  =3D 128         (bitlength =3D 8, INT_MAX =3D 127)
2^15 =3D 32768       (bitlength =3D 16, etc.)
2^31 =3D 2147483648
2^63 =3D 9223372036854775808
All numbers =3D 2^((2^n)-1) where n > 1 end in '8' (See Note)

If you go to an unsigned int, all numbers =3D 2^(2^n) where n > 1
end in '6', and you need to change INT_MAX to UNSIGNED_INT_MAX (I'm
guessing about that, it might be U_INT_MAX or whatever) and change
'8' to '6' in the 'Else If' line.
2^8  =3D 256         (UNSIGNED_INT_MAX =3D 255, bitlength =3D 8)
2^16 =3D 65536       (etc.)
2^32 =3D 4294967296
2^64 =3D 18446744073709551616

If you aren't trusting enough to just believe my statements about
2^(2^n) and 2^((2^n)-1), consider that the numbers 2^(2^n) are
generated by squaring the previous number in the series. The
square of any number  in '6' also ends in '6':

x =3D 10*y + 6    (x, y integers)
x^2 =3D 100y^2 + 6*2*10y + 36
Since (100y^2 + 6*2*10y) is a multiple of 10, ending in '0', the sum
with 36 ends in '6'.

Dividing the numbers 2^(2^n) by 2 gives the second series 2^((2^n)-1),
and the result of dividing a number ending in '6' can only end in '3'
or '8'. Since 3 is odd and the powers of 2 are even (VERY even) the
result must end in '8'.

Finally, if you subtract 9 from a number ending in '0' through '8'
you need to borrow from the second integer from the right. Integer
division by 10 then gives you the same result as (number/10)-1,
which does the 'borrow' after the division.

I hope this is clear and correct, I've been looking at it too long.

Gil

```
 0
Reply gil_johnson 1/23/2010 4:48:04 AM

```Keith Thompson wrote:
> jacob navia <jacob@nospam.org> writes:
>> happy a écrit :
>>> I want to implement atoi function which converts string to an integer.
>>> So I did this :
>>>
>>> int atoi(char str[])
>>> {
>>>   int i, num;
>>>   for( num = 0, i = 0 ; isdigit(str[i]) ; i++)
>>>       num = num * 10 + str[i] - '0' ;
>>>   return num;
>>> }
>>>
>>> Here I wnat to know is there any way to tell user if num goes out of
>>> range of int ?
>>> I mean we can't check num after overflow as it will be UB so is there
>>> a way to check if str[] contains large integer ?
>> Use a double for comparing num*10 against INT_MAX:
>>
>> double d = num;
>> if (d*10 > INT_MAX)
>>    etc
>
> That can fail if double has fewer value bits than int does (e.g., if
> int and double are both 64 bits).
>
> Aside from that, I'd write the above as:
>
>     if (num * 10.0 > INT_MAX) /* ... */

For using double I would do the same thing. However, if writing the
function for real I would simple pre-calculate INT_MAX/10 and INT_MAX%10
so I can do a couple of quick integer comparisons...
if ((num > 0 &&
num < IMAX_DIV_10 ||
num == IMAX_DIV_10 && dig <= IMAX_MOD_10) ||
(num < 0 &&
num > IMIN_DIV_10 ||
num == IMIN_DIV_10 && dig <= IMIN_MOD_10))
/* all OK */

Obviously on pre-calculating you need to ensure you use round towards 0,
where I believe C90 allows round towards -inf, so you need a little
care. It should also allow the common case to fall out fast (if you need
the efficiency), and depending on how you handle negative numbers in
your atoi implementation you could move the sign check else where.
--
Flash Gordon
```
 0
Reply Flash 1/23/2010 11:19:26 AM

```bartc <bartc@freeuk.com> wrote:

> "Jens Thoms Toerring" <jt@toerring.de> wrote in message
> news:7rs87kFt7qU1@mid.uni-berlin.de...
> > Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
> >> On 1/21/2010 6:05 PM, bartc wrote:
> >> > "Jens Thoms Toerring" <jt@toerring.de> wrote
> >> >> [...]
> >> >> char im[ ( CHAR_BIT * sizeof( int ) ) / 3 + 1 ];
> >> >> sprintf( im, "%d\n", INT_MAX );
> >> >> if ( strlen( str ) > strlen( im ) || strcmp( str, im ) > 0 )
> >> >> puts( "overflow" );
> >> >
> >> > I use a similar technique in a real application. But I only do the
> >> > strcmp() test when both strings are the same length, otherwise it goes
> >> > wrong I think.
> >
> >>      So if im[] holds "2147483647" and str is "11111111111111111"
> >> you'll conclude that all's well?
> >
> > I guess that bartc meant that when the length isn't equal you
> > actually don't have to do anymore checks since then the question
> > is already answered (but then, as I just realized, there is ano-
> > ther point that needs to be taken care about: what about strings
> > that start with one or more '0'?). Just the concern about the string
> > being shorter than a "stringified" version of INT_MAX is something I
> > don't get since strcmp() will return -1 if 'str' is shorter than 'im'.

> My strcmp() behaves differently from yours then:

> printf("%d\n", strcmp("9","214748647"));

> outputs 1 on my machine.

Ooops, no, your strcmp() doesn't work differently from mine;-)
- I just considered cases like strcmp("1", "123") only, stupid
me.... So, yes, a correct version will need to compare strings
only of they have exactly the same lengths (and avoiding an un-
necessary strcmp() is better anyway when the result can already
be derived from the lengths).
Regards, Jens
--
\   Jens Thoms Toerring  ___      jt@toerring.de
\__________________________      http://toerring.de
```
 0
Reply jt 1/23/2010 10:30:50 PM

40 Replies
1233 Views

Similar Articles

12/10/2013 9:56:56 PM
page loaded in 46805 ms. (0)

 Reply:

Similar Artilces:

96-bit integer modulo, Athlon64 gcc 64-bit integers, libc codefor 64-bit division, etc.
Hi, To effectively solve a research problem, I need a very fast (sub-microsecond, if possible) method to determine whether one 96-bit integer is an exact multiple of another 96-bit integer. The high-level application is mostly written in Perl and is intended to be portable, but right now I am concentrating on the hardware that I have in-hand, which include 2.4 GHz Xeons, a 1.8 GHz Athlon64 ("3000+), a 1.8GHz Pentium M, and a Mac with a G5 CPU (sorry, I don't know the CPU speed). The x86s (except for the Pentium M) are running Linux, the Pentium M is running Windows XP and the Mac i...

integer checking ?
hi, is there any function in Javascript to check/validate integer value. there is parseInt(val) but it only checks first digit. example : to find error in 123k44 mhk wrote: > hi, > > is there any function in Javascript to check/validate integer value. > there is parseInt(val) but it only checks first digit. > > example : to find error in 123k44 > myVar = "123k44" if (myVar == +myVar) lightly tested. -- Randy comp.lang.javascript FAQ - http://jibbering.com/faq Randy Webb wrote: > mhk wrote: > >> hi, >> >> is there any funct...

Packed Integers
What exactly are packed integers? How do they differ from normal integers? Does it just simply mean that several integers can be packed into one large register, or does it mean a different encoding? I've looked around the web and can't find an answer. luke@ukonline.co.uk wrote: >What exactly are packed integers? How do they differ from normal integers? >Does it just simply mean that several integers can be packed into one large >register, or does it mean a different encoding? I've looked around the web >and can't find an answer. In what context? The term "...

Random Integer Generator
> Pieter Droogendijk wrote > Date: Mon, Aug 18 2003 2:17 pm > Groups: comp.lang.c <snip> > I usually use a function like this: > min+(int) ((double)((max+1)-min)*rand()/(RAND_MAX+1.0)) > to get a random integer between min and max. I've seen > that it's 'random enough' for my taste. No performance > beast though... There is a problem with this. A histogram will show a non-uniform distribution of integers, if the range min:max is a large proportion of RAND_MAX, or not a factor of RAND_MAX. I use the following (by the way, I'm a newbie C pr...

Converting a string to integer.
Hello again. I have another question. I am using 6.5. I have an edit box on a GUI and I need to restrict this entry to an integer value. Is there a way to do this in the property editor? If so How? If Not how can I do this? Below is a sample of code that checks to make sure the edit box is a number but necessarily an integer. AtNu1 = str2double(get(hObject, 'String')); if isnan(AtNu1) set(hObject, 'String', 0); errordlg('Input must be a number','Error'); end On Mon, 28 Jun 2004 23:22:57 -0400, michael lisowski wrote: > Hello again. I have another q...

How to avoid stack overflow in C????
Environement : Sun OS + gnu tools + sun studio (dbx etc) having some Old C-Code (ansi + KR Style) and code inspection shows some big size variable (auto) allocated (on stack) say for ex. char a[8000]; (this type of code and other complex mallc/free etc is used frequently and total approx 450 files, each file is of approx/avg 1000 line, multithreaded , socket code) When i tried to add few new variables of some size (say 1000 bytes) its was crashing. But later I assigned few variable (a[8000]) through calloc call, I was able to add other varibles also, This time code was working fine withou...

integer type returned by size
Is I understand correctly, 'size', and other array inquiry functions return integer of default type. What happens in case the result is too large to fit this type ? Thank you. Eli Osherovich <eli.osherovich@gmail.com> wrote: > Is I understand correctly, 'size', and other array inquiry functions > return integer of default type. > What happens in case the result is too large to fit this type ? See the optional kind= arguments to all the intrinsics for which that is an issue. That is an f2003 feature, added for this exact reason. I suspect that mos...

how to implement: fixed leadig, error on lineheight overflow
Hello, After reading Bringhurst, I was experimenting a bit with getting fixed leadings (baselineskips) and fixed parskips. Getting the rubber out of the parskips was as easy as saying \setlength{\parskip}{1\parskip} However, \setlength{\baselineskip}{1\baselineskip} does not stop the interlinewidth to stretch if there is something that is sticking out (such as a high math expression). (Is there another rubber length I'm missing here?) Ideally, I would like to keep the leading constant (does not seem to correspond to baselineskip), and when something high goes beyond the allowe...

Best way to convert sequence of bytes to long integer
I have a byte string (Python 2.x string), e.g.: s = "g%\$f yg\n1\05" assert len(s) == 10 I wish to convert it to a long integer, treating it as base-256. Currently I'm using: def makelong(s): n = 0 for c in s: n *= 256 n += ord(c) return n which gives: >>> makelong(s) 487088900085839492165893L Is this the best way, or have I missed some standard library function? Thanks in advance, -- Steven Steven D'Aprano, 20.01.2010 08:36: > I have a byte string (Python 2.x string), e.g.: > > s = ...

how to insert new line before integers among reals in array
Hello, 30.11 403.63 21.51 773.37 231.50 50.11 10 36.52 51.52 49.09 12.86 58.91 40.77 21.29 24.56 -0.9 29.98 30.88 333.68 66.50 712.70 230.73 55.69 15 27.46 11.42 49.63 Above are some example data. I want to write a script to identify integers (i.e. 10,15) and then insert a line break before these numbers: 30.11 403.63 21.51 773.37 231.50 50.11 10 36.52 51.52 49.09 12.86 58.91 40.77 21.29 24.56 -0.9 29.98 30.88 333.68 66.50 712.70 230.73 55.69 15 27.46 11.42 49.63 How do I amend the script below to do this task? ...

16-bit integers on 32-bit machine(PowerPC)
I've got a question about the assembly generated for 16-bit integer operations on a 32-bit PowerPC. I have a function in C that has several 16-bit unsigned integer parameters(on my compiler unsigned short int). Let's say the function is as below: unsigned short int foo(unsigned short int x, unsigned short int y) { return x >> y; } The arguments x and y are passed in register r3 and r4 respectively. The first thing that is done in the aseembly listing for this function is that r3 has its most significant 16 bits cleared. I am trying to understand 2 things: (1) Why is only ...

Testing Fortran 90 Compiler for 8-byte integer support
I am working on a Fortran 90 compiler . Recently we have added 8-byte integer support to the Compiler. Now i want to know is there any testing methodology or open-source test suite available to test for 8-byte integer values??????? On Jun 5, 10:34 am, amit chauhan <amit25_chau...@yahoo.co.in> wrote: > I am working on a Fortran 90 compiler . Recently we have added 8-byte > integer support to the Compiler. Now i want to know is there any > testing methodology or open-source test suite available to test for > 8-byte integer values??????? http://gcc.gnu.org/fortran/ conta...

lccwin32 generates MOVs instead of XCHG when swapping a pair of 32bit integers?
Help - are we running low on registers in the following code snippet? Is it generally better to choose MOVL over XCHG? If XCHG is faster, how would one rearrange the C code to get XCHG in the ASM code? Many thanks in advance. // --------------------- Incomplete code snippet --------------------- // Logiciels/Informatique lcc-win32 version 3.8. (Dec 18 2007 19:12:54) // Compile options -v -S -p6 -O 125 IntSwapBuf = *IntPtrL; 126 *IntPtrL = *IntPtrR; 127 *IntPtrR = IntSwapBuf .line 125 movl -8(%ebp),%eax movl (,%eax),%ecx movl %ecx,-20(%ebp) .line 126 m...

Correct way to handle "makes integer from pointer without cast'
I'm unsure about the correct way to write code that doesn't produce gcc's warnings of "makes integer from pointer without cast." In this case, it is using popen, but I guess my question could be reworked to read "do I /really/ have to cast to pointer every single time I use a constant char? Isn't that a lot of extra work, whereas the compiler should be able to detect, analyse, and handle without warning if it's not needed?" With this code: FILE *output; output = popen("/bin/ls", 'r'); gcc warns that: passing argum...