printfDecimal.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <string.h>
  2. #include <math.h>
  3. #include "ft_printf_internal.h"
  4. char getDecimalCount(struct printf_format_params* format, long double* number, char alphabetLen)
  5. {
  6. int result = 7;
  7. int i;
  8. int sign = signbit(*number) ? -1 : 1;
  9. int nextDecimal;
  10. if (format->precision >=0)
  11. return format->precision +1;
  12. *number *= sign;
  13. i = 0;
  14. while (i <= result)
  15. {
  16. *number = *number * alphabetLen;
  17. ++i;
  18. }
  19. nextDecimal = (int) ((*number - (long long) *number) * alphabetLen);
  20. *number = (long long) *number;
  21. if (nextDecimal >= alphabetLen/2)
  22. (*number)++;
  23. while (i)
  24. {
  25. *number = *number / alphabetLen;
  26. --i;
  27. }
  28. *number *= sign;
  29. return result;
  30. }
  31. int printfDecimalSpecial(struct printf_data* data, char isNegative, const char* str)
  32. {
  33. int sign = 0;
  34. int sysCallRet;
  35. if (isNegative)
  36. sign = printfWrite(data, "-", 1);
  37. if (sign < 0)
  38. return sign;
  39. sysCallRet = printfWrite(data, str, 3);
  40. if (sysCallRet < 0)
  41. return sysCallRet;
  42. return sysCallRet + sign;
  43. }
  44. int printDecimals(struct printf_data* data, char decimalToPrint, long double number, const char* alphabet)
  45. {
  46. int sysCallRet;
  47. int result;
  48. int alphabetLen = strlen(alphabet);
  49. if (decimalToPrint < 0)
  50. return 0;
  51. if (number < 0)
  52. number *= -1;
  53. sysCallRet = printfWrite(data, ".", 1);
  54. if (sysCallRet < 0)
  55. return sysCallRet;
  56. result = sysCallRet;
  57. decimalToPrint--;
  58. while (decimalToPrint)
  59. {
  60. number = (number - (int) number) * alphabetLen;
  61. sysCallRet = printfWrite(data, &alphabet[(int)number], 1);
  62. if (sysCallRet < 0)
  63. return sysCallRet;
  64. result += sysCallRet;
  65. decimalToPrint--;
  66. }
  67. return result;
  68. }
  69. int doPrintfF(struct printf_data* data, struct printf_format_params* format, long double number, const char* alphabet)
  70. {
  71. int result;
  72. int decimalToPrint = getDecimalCount(format, &number, strlen(alphabet));
  73. int sysCallRet;
  74. result = printfNumber(data, format, (long long) number, decimalToPrint, alphabet);
  75. if (result < 0)
  76. return result;
  77. sysCallRet = printDecimals(data, decimalToPrint, number, alphabet);
  78. if (sysCallRet < 0)
  79. return sysCallRet;
  80. result += sysCallRet;
  81. if ((format->flags & PRINTF_FLAG_LEFT_PADDING) && !(format->flags & PRINTF_FLAG_ZERO_PAD))
  82. {
  83. sysCallRet = pad(data, format, result);
  84. if (sysCallRet < 0)
  85. return sysCallRet;
  86. result += sysCallRet;
  87. }
  88. return result;
  89. }
  90. int printf_f(struct printf_data* data, struct printf_format_params* format, va_list args)
  91. {
  92. double number = va_arg(args, double);
  93. if (isnan(number))
  94. return printfDecimalSpecial(data, signbit(number), "nan");
  95. if (!isfinite(number))
  96. return printfDecimalSpecial(data, signbit(number), "inf");
  97. return doPrintfF(data, format, number, DEC_ALPHABET);
  98. }
  99. int printf_F(struct printf_data* data, struct printf_format_params* format, va_list args)
  100. {
  101. double number = va_arg(args, double);
  102. if (isnan(number))
  103. return printfDecimalSpecial(data, signbit(number), "NAN");
  104. if (!isfinite(number))
  105. return printfDecimalSpecial(data, signbit(number), "INF");
  106. return doPrintfF(data, format, number, DEC_ALPHABET);
  107. }
  108. int printf_a(struct printf_data* data, struct printf_format_params* format, va_list args)
  109. {
  110. double number = va_arg(args, double);
  111. if (isnan(number))
  112. return printfDecimalSpecial(data, signbit(number), "nan");
  113. if (!isfinite(number))
  114. return printfDecimalSpecial(data, signbit(number), "inf");
  115. format->flags |= PRINTF_FLAG_ALTERNATE_FORM;
  116. format->typeName = printf_x;
  117. return doPrintfF(data, format, number, HEx_ALPHABET);
  118. }
  119. int printf_A(struct printf_data* data, struct printf_format_params* format, va_list args)
  120. {
  121. double number = va_arg(args, double);
  122. if (isnan(number))
  123. return printfDecimalSpecial(data, signbit(number), "NAN");
  124. if (!isfinite(number))
  125. return printfDecimalSpecial(data, signbit(number), "INF");
  126. format->flags |= PRINTF_FLAG_ALTERNATE_FORM;
  127. format->typeName = printf_X;
  128. return doPrintfF(data, format, number, HEX_ALPHABET);
  129. }