libft/ft_printf_tools_float.c
Tanguy MAZE 55767c36c6 plop
added ft_getline WIP
2019-03-07 19:06:02 +01:00

123 lines
3.3 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_printf_tools_float.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tmaze <tmaze@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/02/13 12:52:34 by tmaze #+# #+# */
/* Updated: 2019/03/03 17:36:31 by tmaze ### ########.fr */
/* */
/* ************************************************************************** */
#include "libftprintf.h"
void roundup(char *str, long double n, int i, int prec)
{
int ret;
int len;
ret = 1;
len = ft_strlen(str);
if ((int)n >= 5 && (n - (int)n) > 0.0)
{
while (i-- != 0 && ret == 1)
{
if (str[i] != '.' && str[i] + 1 > '9' && (ret = 1))
str[i] = '0';
else if (str[i] != '.' && !(ret = 0))
str[i]++;
}
if (ret == 1 && (i = ft_strlen(str)) < 4980)
while (--i > 0)
str[i + 1] = str[i];
str[0] = (ret == 1 && i < 4980) ? '1' : str[0];
}
i = 0;
while (str[i] && str[i] != '.')
i++;
i += prec + 1;
while (i < len)
str[i++] = '\0';
}
void getint(char *str, long double n, int *i)
{
uint64_t nb;
long double div;
nb = n;
div = 1;
while ((nb / div) >= 10)
div *= 10;
nb /= div;
while (*i < 4935 && div != 0)
{
str[*i] = (int)nb + '0';
div = (div == 1) ? 0 : (div / 10);
nb = dmod((n / div), 10);
(*i)++;
}
}
char *getnbrstr(long double nb, t_conv *field)
{
char str[4980];
int i;
int j;
ft_bzero(str, 4980);
nb = nb * ((nb < 0.0) ? -1 : 1);
i = 0;
getint(str, nb, &i);
j = 0;
if (field->fl_prec > 0 || field->fl_hashtag)
str[i++] = '.';
nb = (nb - (uint64_t)nb) * ((nb < 0.0) ? -1 : 1) * 10;
while (j < field->fl_prec && i + j < 4980)
{
str[i + j] = (uint64_t)nb + '0';
nb = (nb - (uint64_t)nb) * 10;
j++;
}
i += j;
roundup(str, nb, i, field->fl_prec);
return (ft_strdup(str));
}
void set_strf(t_conv *f, char *nbrstr, long double nb, int pad)
{
if (!f->fl_minus && !f->fl_zero)
ft_memset(f->str, ' ', (pad > 0) ? pad : 0);
if (nb < 0.0)
f->str[ft_strlen(f->str)] = '-';
else if (f->fl_plus || f->fl_space)
f->str[ft_strlen(f->str)] = (f->fl_plus) ? '+' : ' ';
if (!f->fl_minus && f->fl_zero)
ft_memset(&f->str[ft_strlen(f->str)], '0', (pad > 0) ? pad : 0);
ft_strcat(f->str, nbrstr);
if (f->fl_minus)
ft_memset(&f->str[ft_strlen(f->str)], ' ', (pad > 0) ? pad : 0);
}
char *handle_output_float(t_conv *field, va_list ap)
{
long double nb;
int pad;
int size;
char *nbrstr;
if (field->fl_size == L)
nb = (long double)va_arg(ap, long double);
else
nb = (long double)va_arg(ap, double);
field->fl_prec = (field->fl_prec == -1) ? 6 : field->fl_prec;
nbrstr = getnbrstr(nb, field);
size = set_malloc_sizef(nb, nbrstr, field);
pad = field->str_size - size;
if ((field->str = ft_strnewb(field->str_size)) != NULL)
set_strf(field, nbrstr, nb, pad);
ft_strdel(&nbrstr);
return (field->str);
}