How to Make atoi huge-numbers proof?

298 Views Asked by At

hello I'm trying to recreate atoi in with some other added conditions, mainly computing how many signs and returning the number positive if number of minus even , otherwise negative, the script works fine. the problem it should be created with int type and it will be tested with some really big numbers, such as 19999999999 , I tried to cast it's return value but stupidly forget it will return always it's type. any idea ? thanks

#include <stdio.h>

int ft_checksign(char *str)
{
    int i;
    int sign;

    sign = 0;
    i = 0;
    while (*(str + i))
    {
        if (*(str + i) == '-')
            sign += 1;
        i++;
    }
    return (sign);
}

int ft_atoi(char *str)
{
    long long result;
    int i;

    i = 0;
    result = 0;
    while ((*(str + i) >= 9 && *(str + i) <= 32)
        || *(str + i) == '-' || *(str + i) == '+')
        i++;
    while (*(str + i) && (*(str + i) >= '0' && *(str + i) <= '9'))
    {
        result *= 10;
        result += (long long)str[i] - '0';
        i++;
    }
    if (ft_checksign(str) % 2 == 1)
        return ((long long)-result);
    else
        return ((long long)result);
}
int main()
{
    printf("%i", ft_atoi("19999999999"));
    return 0;
}

OUTPUT

-1474836481
1

There are 1 best solutions below

0
Erdal Küçük On

In the comments section above you're saying: "I was tasked making atoa big-numbers proof."

Luckily we have the strtoxx functions but that is not the issue here.

Lets take a look to the atoi documentation:

Description

The atoi() function converts the initial portion of the string ... to int ... except that atoi() does not detect errors.

Return Value

The converted value or 0 on error.

Bugs

errno is not set on error so there is no way to distinguish between 0 as an error and as the converted value. No checks for overflow or underflow are done. ...

If you consider, that int has either 16 or 32 bits, you're limited to a certain range. Not to forget, that int is a signed type, which means, that one bit is reserved for the sign.

The problem you have to solve is simple: implement an atoi function, so that it is possible to distinguish between 0 or an error and implement checks for overflow and underflow. Since errno is not set, errno is global, set it accordingly.

From man strtol:

Return Value

The strtol() function returns the result of the conversion, unless the value would underflow or overflow. If an underflow occurs, strtol() returns LONG_MIN. If an overflow occurs, strtol() returns LONG_MAX. In both cases, errno is set to ERANGE.

Errors

ERANGE The resulting value was out of range.

The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).

And last but not least: strtol.c