convertbase presque au point juste gerer le max lu

This commit is contained in:
Hugo LAMY
2020-02-20 18:37:36 +01:00
parent 63a0ce084b
commit b17ba4308f
2 changed files with 132 additions and 57 deletions

2
.gitignore vendored
View File

@@ -53,6 +53,8 @@ dkms.conf
# OS generated files # # OS generated files #
*.swp *.swp
*.swo
*.~
.DS_Store .DS_Store
.DS_Store? .DS_Store?
._* ._*

View File

@@ -1,86 +1,159 @@
/* ************************************************************************** */ /*
/* */ ** take a string that is a number in a certain and convert it in another base
/* ::: :::::::: */ ** return the new string
/* ft_convertbase.c :+: :+: :+: */ */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ #include <stdio.h> // for printf
/* Created: 2018/11/16 15:15:55 by hulamy #+# #+# */ #include <stdlib.h> // for atoi
/* Updated: 2020/02/19 18:47:35 by hulamy ### ########.fr */
/* */ char *ft_convertbase(char *nbr, char *base_from, char *base_to);
/* ************************************************************************** */
int main(int ac, char **av)
{
if (ac != 4)
printf("usage:\nchar *nbr, char *base_from, char *base_to\ntry the max long unsigned int : 9223372036854775807");
else
printf("[%s]\n",ft_convertbase(av[1], av[2], av[3]));
return (0);
}
#include "libft.h" #include "libft.h"
static int ft_malloc_size(int decimal, int length, int i) /*
{ ** check :
if (decimal <= 0) ** -if the base has no characters that appear more than one time
i++; ** -if the signes '-' and '+' are not part of the set
while (decimal) ** -if there are no invisible characters (inferior to 32 or equal to 127)
{ */
decimal /= length;
i++;
}
return (i);
}
static char *ft_decimal_to_base(int decimal, char *base, char *res, int size) int
is_valid_base(char *base)
{ {
long nb;
int i; int i;
nb = decimal;
i = 0;
while (base[i])
i++;
if (nb < 0)
nb = -nb;
while (--size >= 0)
{
res[size] = base[nb % i];
nb /= i;
}
return (res);
}
static int ft_base_to_decimal(char *nbr, char *base, int length, int i)
{
long decimal;
int j; int j;
decimal = 0; i = 0;
if (nbr[i] == '-') while (base[i])
{
j = i + 1;
while (base[j])
if (base[i] == base[j++])
return (0);
if (base[i] == '-' || base[i] == '+' || base[i] < 33 || base[i] == 127)
return (0);
i++; i++;
}
if (i >= 2)
return (1);
return (0);
}
/*
** check :
** -if base is valid
** -if nbr contain characters
** -if nbr is made of elements of base only
*/
int
is_valid_nbr(char *nbr, char *base)
{
int i;
int j;
i = 0;
if (!is_valid_base(base))
return (0);
while (nbr[i])
{
j = 0;
while (base[j] && nbr[i] != base[j])
j++;
if (base[j] == '\0')
return (0);
i++;
}
if (i == 0)
return (0);
return (1);
}
/*
** -transform a nbr written as a string into a decimal nbr
** -it's an unsigned nbr because the negativity is managed elsewhere
** -if the number is bigger than the max unsigned long int it's false
*/
unsigned long int
base_to_decimal(char *nbr, char *base)
{
unsigned long int decimal;
int i;
int j;
int length;
decimal = 0;
i = 0;
length = 0;
while (base[length])
length++;
while (nbr[i]) while (nbr[i])
{ {
j = 0; j = 0;
while (nbr[i] != base[j] && base[j]) while (nbr[i] != base[j] && base[j])
j++; j++;
if ((18446744073709551615U - j) / length > decimal)
return (0);
decimal = (decimal * length) + j; decimal = (decimal * length) + j;
i++; i++;
} }
if (nbr[0] == '-')
decimal = -decimal;
return (decimal); return (decimal);
} }
char *ft_convertbase(char *nbr, char *base_from, char *base_to) char
*decimal_to_base(unsigned long int decimal, char *base, int malloc_size)
{
int base_size;
int neg;
char *result;
unsigned long int nb;
neg = malloc_size;
base_size = 0;
while (base[base_size])
base_size++;
nb = decimal;
while (nb /= base_size)
malloc_size++;
result = (char *)malloc(sizeof(char) * (malloc_size + 2));
result[malloc_size + 1] = '\0';
if (neg)
result[0] = '-';
while (malloc_size >= 0)
{
result[malloc_size--] = base[decimal % base_size];
decimal /= base_size;
}
return (result);
}
char
*ft_convertbase(char *nbr, char *base_from, char *base_to)
{ {
int length; int length;
int size; unsigned long int decimal;
int decimal;
char *res;
res = 0;
length = 0; length = 0;
while (base_from[length]) if (nbr[0] == '-')
length++; {
decimal = ft_base_to_decimal(nbr, base_from, length, 0); nbr++;
length = 0; length = 1;
while (base_to[length]) }
length++; if (!is_valid_nbr(nbr, base_from) || !is_valid_base(base_to))
size = ft_malloc_size(decimal, length, 0); return (NULL);
res = (char *)malloc(sizeof(char) * (size + 1)); if ((decimal = base_to_decimal(nbr, base_from)) == 0)
res[size] = '\0'; return (NULL);
return (ft_decimal_to_base(decimal, base_to, res, size)); return (decimal_to_base(decimal, base_to, length));
} }