📄 stdiop_f.c
字号:
/*-----------------------------------------------------------------*/
width -= (buf_size - curr);
/*-----------------------------------------------------------------*/
/* Pad with spaces to the left until width. */
/*-----------------------------------------------------------------*/
if (send_chars(stream, ' ', width))
return -1;
if (width > 0)
printed_bytes += width;
/*-----------------------------------------------------------------*/
/* Send either one '+' or ' ' if necessary. */
/*-----------------------------------------------------------------*/
if (add == PLUS_SIGN)
{
if (send_char(stream, '+'))
return -1;
++printed_bytes;
}
else if (add == SPACE_SIGN)
{
if (send_char(stream, ' '))
return -1;
++printed_bytes;
}
/*-----------------------------------------------------------------*/
/* Now, output the contents of the buffer, buf. */
/*-----------------------------------------------------------------*/
if (send_buf(stream, &buf[curr], buf_size - curr))
return -1;
printed_bytes += (buf_size - curr);
}
return printed_bytes;
}
/***********************************************************************/
/* get_exponent: Extract exponent from a floating point number */
/* */
/* Input: f_ptr = pointer to the floating point number */
/* */
/* Returns: exponent of the floating point number */
/* */
/***********************************************************************/
static int get_exponent(double *f_ptr)
{
int r_value = 0;
real real_num;
double i, exp;
int temp;
/*-------------------------------------------------------------------*/
/* If a pointer to a zero value is passed, return 0. */
/*-------------------------------------------------------------------*/
if (!*f_ptr)
return r_value;
/*-------------------------------------------------------------------*/
/* Get the exponent in base 2 and subtract the bias (1023). */
/*-------------------------------------------------------------------*/
real_num.real = *f_ptr;
temp = (int)real_num.exponent - 1023;
exp = (double)temp;
/*-------------------------------------------------------------------*/
/* If exponent is negative, make it positive, transform it in base */
/* 10, and multiply. */
/*-------------------------------------------------------------------*/
if (exp < 0)
{
exp = -exp;
exp *= log10(2);
exp = modf(exp, &i);
r_value = (int)-i;
exp = modf(pow(10, i) + 0.5, &i);
*f_ptr *= i;
}
/*-------------------------------------------------------------------*/
/* Else if exponent positive, transform it in base 10, and divide. */
/*-------------------------------------------------------------------*/
else if (exp > 0)
{
exp *= log10(2);
exp = modf(exp, &i);
r_value = (int)i;
exp = modf(pow(10, i) + 0.5, &i);
*f_ptr /= i;
}
/*-------------------------------------------------------------------*/
/* As long as the float is not between 1 and 10, adjust it. */
/*-------------------------------------------------------------------*/
while (*f_ptr < 1 || *f_ptr >= 10)
{
if (*f_ptr < 1)
{
*f_ptr *= 10;
--r_value;
}
else
{
*f_ptr /= 10;
++r_value;
}
}
return r_value;
}
/***********************************************************************/
/* round_up: Round up the number in buf to precision and get rid of */
/* trailing zeros if necessary. */
/* */
/* Inputs: buf = buffer that stores the number */
/* precision = number of digits to be rounded */
/* zeros = flag to keep or disregard trailing zeros */
/* exponent = pointer to the value of the exponent */
/* */
/* Returns: number of digits in buffer */
/* */
/***********************************************************************/
static int round_up(char *buf, int precision, int zeros, int *exponent)
{
int r_value = 2, i, exp, next_time = 0;
/*-------------------------------------------------------------------*/
/* If precision is 0, there is no rounding off, so just return the */
/* integral part of the number. */
/*-------------------------------------------------------------------*/
if (!precision)
return r_value;
if (precision < 20 && buf[precision + 3] >= '5')
{
/*-----------------------------------------------------------------*/
/* Round up the precision(th) digit. */
/*-----------------------------------------------------------------*/
i = precision + 2;
for (;;)
{
/*---------------------------------------------------------------*/
/* If i is 2, buf[i] = '.' so skip it. */
/*---------------------------------------------------------------*/
if (i != 2)
{
/*-------------------------------------------------------------*/
/* If i is 1 and buf[i] = '9', it's 9.999... which rounded is */
/* 1.00000 with the exponent increased. */
/*-------------------------------------------------------------*/
if (i == 1 && buf[i] == '9')
{
for (i = precision + 3; i > 3; --i)
buf[i] = '0';
buf[3] = '0';
buf[1] = '1';
++(*exponent);
break;
}
/*-------------------------------------------------------------*/
/* If buf[i] is 0-8, increment current digit by 1 and return. */
/*-------------------------------------------------------------*/
if (buf[i] != '9')
{
buf[i] += 1;
break;
}
/*-------------------------------------------------------------*/
/* Else buf[i] is '9', so make digit '0' and move one digit */
/* to the left (i--). */
/*-------------------------------------------------------------*/
else
{
buf[i--] = '0';
}
}
/*---------------------------------------------------------------*/
/* Else i is 2 so skip '.'. */
/*---------------------------------------------------------------*/
else
--i;
}
for (i = precision + 3; i < 23; ++i)
/*---------------------------------------------------------------*/
/* Fill out the rest of the buffer with 0's. */
/*---------------------------------------------------------------*/
buf[i] = '0';
}
/*-------------------------------------------------------------------*/
/* Adjust the exponent. */
/*-------------------------------------------------------------------*/
exp = *exponent;
if (exp < 0)
exp = -exp;
for (i = 28; i >= 25; --i)
{
if (next_time)
exp = 0;
buf[i] = (char)(exp % 10 + '0');
if (exp < 10)
next_time = 1;
else
exp /= 10;
}
r_value = precision + 2;
if (!zeros)
for (i = precision + 2;; --i)
{
/*---------------------------------------------------------------*/
/* Get rid of trailing zeros. */
/*---------------------------------------------------------------*/
if (i <= 2)
return 2;
else if (buf[i] != '0')
return r_value;
else
--r_value;
}
return r_value;
}
/***********************************************************************/
/* print_rbuf: Print real_buf to stream */
/* */
/* Inputs: stream = output on which real_buf is printed */
/* real_buf = string that is printed to the output */
/* width = width of number to be printed */
/* flags = printf flags (#, 0, -) */
/* spec = 'f', 'e', or 'E' specifier */
/* precision = precision specified (6 default) */
/* zeros = flag for trailing zeros */
/* */
/* Returns: Number of bytes printed, -1 on error */
/* */
/***********************************************************************/
static int print_rbuf(FILE *stream, char *real_buf, int width, int flags,
char spec, int precision, int zeros)
{
int exponent = 1000 * (real_buf[25] - '0') + 100 * (real_buf[26] - '0')
+ 10 * (real_buf[27] - '0') + real_buf[28] - '0';
int spaces = 0, change_point = 0, when = 0, d_digits = 0, start = 0;
int start_count = 0, times = 0, added_sign = 0, e_d = 4, i, j;
int num_digits, printed_bytes = 0;
char spc;
/*-------------------------------------------------------------------*/
/* If function is called with 'g' and '#', include trailling zeros. */
/*-------------------------------------------------------------------*/
if (!zeros && (flags & NUM_FLAG))
zeros = WZ;
/*-------------------------------------------------------------------*/
/* If buf starts with '-', put sign in front of the number. */
/*-------------------------------------------------------------------*/
if (real_buf[0] == '-')
added_sign = 1;
else if (flags & PLUS_FLAG)
added_sign = 1;
else if (flags & SPACE_FLAG)
{
added_sign = 1;
real_buf[0] = 32;
}
/*-------------------------------------------------------------------*/
/* Find out how many digits the number will have. */
/*-------------------------------------------------------------------*/
if (exponent > 99)
++e_d;
if (exponent > 999)
++e_d;
if (!precision && (flags & NUM_FLAG))
++e_d;
num_digits = precision ? 2 + precision + added_sign : 1 + added_sign;
if (spec != 'f')
{
exponent = (real_buf[24] == '-') ? -exponent : exponent;
d_digits = round_up(real_buf, precision, zeros, &exponent);
}
num_digits = (spec == 'f') ? num_digits + exponent : d_digits + e_d;
if (spec != 'f' && (d_digits == 2) && !(flags & NUM_FLAG))
--num_digits;
if (spec == 'f' && !zeros)
for (i = precision + 2; real_buf[i] == '0'; --i, --num_digits) ;
/*-------------------------------------------------------------------*/
/* Get the correct sign for exponent and round up to precision + 1 */
/* so that 0.9999... won't round up to 1.000... afterwards. */
/*-------------------------------------------------------------------*/
exponent = (real_buf[24] == '-') ? -exponent : exponent;
round_up(real_buf, precision + 1, zeros, &exponent);
if (exponent == 0)
real_buf[24] = '+';
if (num_digits < width)
{
/*-----------------------------------------------------------------*/
/* Pad, depending on the flag with 0s or spaces. */
/*-----------------------------------------------------------------*/
if (flags & MINUS_FLAG)
spaces = width - num_digits;
else
{
spc = (char)((flags & ZERO_FLAG) ? '0' : ' ');
/*---------------------------------------------------------------*/
/* If padding with 0s, put the sign first if necessary. */
/*---------------------------------------------------------------*/
if ((spc == '0') && added_sign)
{
if (send_char(stream, real_buf[0]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -