| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #include <string.h>
- #include <math.h>
- #include "ft_printf_internal.h"
- char getDecimalCount(struct printf_format_params* format, long double* number, char alphabetLen)
- {
- int result = 7;
- int i;
- int sign = signbit(*number) ? -1 : 1;
- int nextDecimal;
- if (format->precision >=0)
- return format->precision +1;
- *number *= sign;
- i = 0;
- while (i <= result)
- {
- *number = *number * alphabetLen;
- ++i;
- }
- nextDecimal = (int) ((*number - (long long) *number) * alphabetLen);
- *number = (long long) *number;
- if (nextDecimal >= alphabetLen/2)
- (*number)++;
- while (i)
- {
- *number = *number / alphabetLen;
- --i;
- }
- *number *= sign;
- return result;
- }
- int printfDecimalSpecial(struct printf_data* data, char isNegative, const char* str)
- {
- int sign = 0;
- int sysCallRet;
- if (isNegative)
- sign = printfWrite(data, "-", 1);
- if (sign < 0)
- return sign;
- sysCallRet = printfWrite(data, str, 3);
- if (sysCallRet < 0)
- return sysCallRet;
- return sysCallRet + sign;
- }
- int printDecimals(struct printf_data* data, char decimalToPrint, long double number, const char* alphabet)
- {
- int sysCallRet;
- int result;
- int alphabetLen = strlen(alphabet);
- if (decimalToPrint < 0)
- return 0;
- if (number < 0)
- number *= -1;
- sysCallRet = printfWrite(data, ".", 1);
- if (sysCallRet < 0)
- return sysCallRet;
- result = sysCallRet;
- decimalToPrint--;
- while (decimalToPrint)
- {
- number = (number - (int) number) * alphabetLen;
- sysCallRet = printfWrite(data, &alphabet[(int)number], 1);
- if (sysCallRet < 0)
- return sysCallRet;
- result += sysCallRet;
- decimalToPrint--;
- }
- return result;
- }
- int doPrintfF(struct printf_data* data, struct printf_format_params* format, long double number, const char* alphabet)
- {
- int result;
- int decimalToPrint = getDecimalCount(format, &number, strlen(alphabet));
- int sysCallRet;
- result = printfNumber(data, format, (long long) number, decimalToPrint, alphabet);
- if (result < 0)
- return result;
- sysCallRet = printDecimals(data, decimalToPrint, number, alphabet);
- if (sysCallRet < 0)
- return sysCallRet;
- result += sysCallRet;
- if ((format->flags & PRINTF_FLAG_LEFT_PADDING) && !(format->flags & PRINTF_FLAG_ZERO_PAD))
- {
- sysCallRet = pad(data, format, result);
- if (sysCallRet < 0)
- return sysCallRet;
- result += sysCallRet;
- }
- return result;
- }
- int printf_f(struct printf_data* data, struct printf_format_params* format, va_list args)
- {
- double number = va_arg(args, double);
- if (isnan(number))
- return printfDecimalSpecial(data, signbit(number), "nan");
- if (!isfinite(number))
- return printfDecimalSpecial(data, signbit(number), "inf");
- return doPrintfF(data, format, number, DEC_ALPHABET);
- }
- int printf_F(struct printf_data* data, struct printf_format_params* format, va_list args)
- {
- double number = va_arg(args, double);
- if (isnan(number))
- return printfDecimalSpecial(data, signbit(number), "NAN");
- if (!isfinite(number))
- return printfDecimalSpecial(data, signbit(number), "INF");
- return doPrintfF(data, format, number, DEC_ALPHABET);
- }
- int printf_a(struct printf_data* data, struct printf_format_params* format, va_list args)
- {
- double number = va_arg(args, double);
- if (isnan(number))
- return printfDecimalSpecial(data, signbit(number), "nan");
- if (!isfinite(number))
- return printfDecimalSpecial(data, signbit(number), "inf");
- format->flags |= PRINTF_FLAG_ALTERNATE_FORM;
- format->typeName = printf_x;
- return doPrintfF(data, format, number, HEx_ALPHABET);
- }
- int printf_A(struct printf_data* data, struct printf_format_params* format, va_list args)
- {
- double number = va_arg(args, double);
- if (isnan(number))
- return printfDecimalSpecial(data, signbit(number), "NAN");
- if (!isfinite(number))
- return printfDecimalSpecial(data, signbit(number), "INF");
- format->flags |= PRINTF_FLAG_ALTERNATE_FORM;
- format->typeName = printf_X;
- return doPrintfF(data, format, number, HEX_ALPHABET);
- }
|