The bug is that your ft_putnbr()
function takes an int
parameter. There're two problems with that when you pass it a variable of type unsigned long
as in this case. Both can be replicated with this snippet:
#include <limits.h>
#include <stdio.h>
int main() {
unsigned long my_long = ULONG_MAX;
int my_int = (int) my_long;
printf("%lu\n", my_long);
printf("%i\n", my_int);
}
The first problem is that the parameter is of a type of shorter length than the value you try to pass to the function. Let's assume that long
is 2 bytes on our system while int
is 1 byte (more realistically they would be 4 or 8 bytes). In binary, ULONG_MAX
would then be 1111 1111 1111 1111
. However, when assigning that to int
, which only is 1 byte, the value will be 1111 1111
as there's only room for 8 bits. In order to pass ULONG_MAX
, we need a type of the same (or greater) length so there's room for all bits. For example, we could use long
so that the function signature becomes ft_putnbr(long nb);
.
There's, however, still one problem. The type long
is signed (i.e., one of the bits is dedicated to keep track of whether the number is negative or positive) while ULONG_MAX
is of unsigned type (i.e., only positive). In particular, if the first bit is 1, then that indicates that the number is negative. So a signed 2 byte type with binary value 1111 1111 1111 1111
will be negative. The reason that it becomes (decimal) -1
is beyond this answer (but you can read about it here: http://en.wikipedia.org/wiki/Two%27s_complement).
So, how can we solve both of these problems? One approach would be to let ft_putnbr()
take a very wide signed type (e.g., long long
) and never pass it any unsigned type of equal or greater length. Another approach would be to write two ft_putnbr()
(with different names): one that takes the widest signed type and one that takes the widest unsigned type.