Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strtol() and atol() do not convert strings larger than 9 digits

while working on an application that requires converting strings to long numbers the atol() and strtol() could not convert any string larger than 9 digits correctly.

strtol would prompt a number that has nothing to do with the string, while atol results in a negative number (overflow).

any idea why this is happening and how can i fix it?

like image 794
Nataly Avatar asked Feb 11 '11 17:02

Nataly


2 Answers

It sounds like a long on your system is a 32-bit value. That means any unsigned number above 4,294,967,295 won't convert correctly, and neither will signed numbers above 2,147,483,647 or below 2,147,483,648.

In general, an n-bit representation can represent signed numbers in the range [-2n-1,-2n-1) or unsigned numbers in the range [0,2n).

The wikipedia article Computer numbering formats is probably a good jumping off point to learn more about this behaviour.

The reason you see different results from atol() and strtol() is because they have different error handling characteristics. From the strtol() man page:

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.

And from the atol() man page:

The atoi() function converts the initial portion of the string pointed to by nptr to int. The behaviour is the same as

strtol(nptr, (char **)NULL, 10);

except that atoi() does not detect errors.

The atol() and atoll() functions behave the same as atoi(), except that they convert the initial portion of the string to their return type of long or long long.

like image 196
Carl Norum Avatar answered Nov 04 '22 08:11

Carl Norum


This probably has to do with the size of a long on your platform. On 32-bit platforms, the largest value that fits in a long is 2147483647 (2^31-1), so anything larger than that simply won't fit. Use long long and strtoll instead.

like image 34
Fred Foo Avatar answered Nov 04 '22 08:11

Fred Foo