⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vasnprintf.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 5 页
字号:
				   * sizeof (mp_limb_t));  if (pow5_ptr == NULL)    {      free (memory);      return NULL;    }  /* Initialize with 1.  */  pow5_ptr[0] = 1;  pow5_len = 1;  /* Multiply with 5^|n|.  */  if (abs_n > 0)    {      static mp_limb_t const small_pow5[13 + 1] =	{	  1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,	  48828125, 244140625, 1220703125	};      unsigned int n13;      for (n13 = 0; n13 <= abs_n; n13 += 13)	{	  mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];	  size_t j;	  mp_twolimb_t carry = 0;	  for (j = 0; j < pow5_len; j++)	    {	      mp_limb_t digit2 = pow5_ptr[j];	      carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;	      pow5_ptr[j] = (mp_limb_t) carry;	      carry = carry >> GMP_LIMB_BITS;	    }	  if (carry > 0)	    pow5_ptr[pow5_len++] = (mp_limb_t) carry;	}    }  s_limbs = abs_s / GMP_LIMB_BITS;  s_bits = abs_s % GMP_LIMB_BITS;  if (n >= 0 ? s >= 0 : s <= 0)    {      /* Multiply with 2^|s|.  */      if (s_bits > 0)	{	  mp_limb_t *ptr = pow5_ptr;	  mp_twolimb_t accu = 0;	  size_t count;	  for (count = pow5_len; count > 0; count--)	    {	      accu += (mp_twolimb_t) *ptr << s_bits;	      *ptr++ = (mp_limb_t) accu;	      accu = accu >> GMP_LIMB_BITS;	    }	  if (accu > 0)	    {	      *ptr = (mp_limb_t) accu;	      pow5_len++;	    }	}      if (s_limbs > 0)	{	  size_t count;	  for (count = pow5_len; count > 0;)	    {	      count--;	      pow5_ptr[s_limbs + count] = pow5_ptr[count];	    }	  for (count = s_limbs; count > 0;)	    {	      count--;	      pow5_ptr[count] = 0;	    }	  pow5_len += s_limbs;	}      pow5.limbs = pow5_ptr;      pow5.nlimbs = pow5_len;      if (n >= 0)	{	  /* Multiply m with pow5.  No division needed.  */	  z_memory = multiply (m, pow5, &z);	}      else	{	  /* Divide m by pow5 and round.  */	  z_memory = divide (m, pow5, &z);	}    }  else    {      pow5.limbs = pow5_ptr;      pow5.nlimbs = pow5_len;      if (n >= 0)	{	  /* n >= 0, s < 0.	     Multiply m with pow5, then divide by 2^|s|.  */	  mpn_t numerator;	  mpn_t denominator;	  void *tmp_memory;	  tmp_memory = multiply (m, pow5, &numerator);	  if (tmp_memory == NULL)	    {	      free (pow5_ptr);	      free (memory);	      return NULL;	    }	  /* Construct 2^|s|.  */	  {	    mp_limb_t *ptr = pow5_ptr + pow5_len;	    size_t i;	    for (i = 0; i < s_limbs; i++)	      ptr[i] = 0;	    ptr[s_limbs] = (mp_limb_t) 1 << s_bits;	    denominator.limbs = ptr;	    denominator.nlimbs = s_limbs + 1;	  }	  z_memory = divide (numerator, denominator, &z);	  free (tmp_memory);	}      else	{	  /* n < 0, s > 0.	     Multiply m with 2^s, then divide by pow5.  */	  mpn_t numerator;	  mp_limb_t *num_ptr;	  num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)					  * sizeof (mp_limb_t));	  if (num_ptr == NULL)	    {	      free (pow5_ptr);	      free (memory);	      return NULL;	    }	  {	    mp_limb_t *destptr = num_ptr;	    {	      size_t i;	      for (i = 0; i < s_limbs; i++)		*destptr++ = 0;	    }	    if (s_bits > 0)	      {		const mp_limb_t *sourceptr = m.limbs;		mp_twolimb_t accu = 0;		size_t count;		for (count = m.nlimbs; count > 0; count--)		  {		    accu += (mp_twolimb_t) *sourceptr++ << s_bits;		    *destptr++ = (mp_limb_t) accu;		    accu = accu >> GMP_LIMB_BITS;		  }		if (accu > 0)		  *destptr++ = (mp_limb_t) accu;	      }	    else	      {		const mp_limb_t *sourceptr = m.limbs;		size_t count;		for (count = m.nlimbs; count > 0; count--)		  *destptr++ = *sourceptr++;	      }	    numerator.limbs = num_ptr;	    numerator.nlimbs = destptr - num_ptr;	  }	  z_memory = divide (numerator, pow5, &z);	  free (num_ptr);	}    }  free (pow5_ptr);  free (memory);  /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */  if (z_memory == NULL)    return NULL;  digits = convert_to_decimal (z, extra_zeroes);  free (z_memory);  return digits;}# if NEED_PRINTF_LONG_DOUBLE/* Assuming x is finite and >= 0, and n is an integer:   Returns the decimal representation of round (x * 10^n).   Return the allocated memory - containing the decimal digits in low-to-high   order, terminated with a NUL character - in case of success, NULL in case   of memory allocation failure.  */static char *scale10_round_decimal_long_double (long double x, int n){  int e;  mpn_t m;  void *memory = decode_long_double (x, &e, &m);  return scale10_round_decimal_decoded (e, m, memory, n);}# endif# if NEED_PRINTF_DOUBLE/* Assuming x is finite and >= 0, and n is an integer:   Returns the decimal representation of round (x * 10^n).   Return the allocated memory - containing the decimal digits in low-to-high   order, terminated with a NUL character - in case of success, NULL in case   of memory allocation failure.  */static char *scale10_round_decimal_double (double x, int n){  int e;  mpn_t m;  void *memory = decode_double (x, &e, &m);  return scale10_round_decimal_decoded (e, m, memory, n);}# endif# if NEED_PRINTF_LONG_DOUBLE/* Assuming x is finite and > 0:   Return an approximation for n with 10^n <= x < 10^(n+1).   The approximation is usually the right n, but may be off by 1 sometimes.  */static intfloorlog10l (long double x){  int exp;  long double y;  double z;  double l;  /* Split into exponential part and mantissa.  */  y = frexpl (x, &exp);  if (!(y >= 0.0L && y < 1.0L))    abort ();  if (y == 0.0L)    return INT_MIN;  if (y < 0.5L)    {      while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))	{	  y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));	  exp -= GMP_LIMB_BITS;	}      if (y < (1.0L / (1 << 16)))	{	  y *= 1.0L * (1 << 16);	  exp -= 16;	}      if (y < (1.0L / (1 << 8)))	{	  y *= 1.0L * (1 << 8);	  exp -= 8;	}      if (y < (1.0L / (1 << 4)))	{	  y *= 1.0L * (1 << 4);	  exp -= 4;	}      if (y < (1.0L / (1 << 2)))	{	  y *= 1.0L * (1 << 2);	  exp -= 2;	}      if (y < (1.0L / (1 << 1)))	{	  y *= 1.0L * (1 << 1);	  exp -= 1;	}    }  if (!(y >= 0.5L && y < 1.0L))    abort ();  /* Compute an approximation for l = log2(x) = exp + log2(y).  */  l = exp;  z = y;  if (z < 0.70710678118654752444)    {      z *= 1.4142135623730950488;      l -= 0.5;    }  if (z < 0.8408964152537145431)    {      z *= 1.1892071150027210667;      l -= 0.25;    }  if (z < 0.91700404320467123175)    {      z *= 1.0905077326652576592;      l -= 0.125;    }  if (z < 0.9576032806985736469)    {      z *= 1.0442737824274138403;      l -= 0.0625;    }  /* Now 0.95 <= z <= 1.01.  */  z = 1 - z;  /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...     Four terms are enough to get an approximation with error < 10^-7.  */  l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));  /* Finally multiply with log(2)/log(10), yields an approximation for     log10(x).  */  l *= 0.30102999566398119523;  /* Round down to the next integer.  */  return (int) l + (l < 0 ? -1 : 0);}# endif# if NEED_PRINTF_DOUBLE/* Assuming x is finite and > 0:   Return an approximation for n with 10^n <= x < 10^(n+1).   The approximation is usually the right n, but may be off by 1 sometimes.  */static intfloorlog10 (double x){  int exp;  double y;  double z;  double l;  /* Split into exponential part and mantissa.  */  y = frexp (x, &exp);  if (!(y >= 0.0 && y < 1.0))    abort ();  if (y == 0.0)    return INT_MIN;  if (y < 0.5)    {      while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))	{	  y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));	  exp -= GMP_LIMB_BITS;	}      if (y < (1.0 / (1 << 16)))	{	  y *= 1.0 * (1 << 16);	  exp -= 16;	}      if (y < (1.0 / (1 << 8)))	{	  y *= 1.0 * (1 << 8);	  exp -= 8;	}      if (y < (1.0 / (1 << 4)))	{	  y *= 1.0 * (1 << 4);	  exp -= 4;	}      if (y < (1.0 / (1 << 2)))	{	  y *= 1.0 * (1 << 2);	  exp -= 2;	}      if (y < (1.0 / (1 << 1)))	{	  y *= 1.0 * (1 << 1);	  exp -= 1;	}    }  if (!(y >= 0.5 && y < 1.0))    abort ();  /* Compute an approximation for l = log2(x) = exp + log2(y).  */  l = exp;  z = y;  if (z < 0.70710678118654752444)    {      z *= 1.4142135623730950488;      l -= 0.5;    }  if (z < 0.8408964152537145431)    {      z *= 1.1892071150027210667;      l -= 0.25;    }  if (z < 0.91700404320467123175)    {      z *= 1.0905077326652576592;      l -= 0.125;    }  if (z < 0.9576032806985736469)    {      z *= 1.0442737824274138403;      l -= 0.0625;    }  /* Now 0.95 <= z <= 1.01.  */  z = 1 - z;  /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...     Four terms are enough to get an approximation with error < 10^-7.  */  l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));  /* Finally multiply with log(2)/log(10), yields an approximation for     log10(x).  */  l *= 0.30102999566398119523;  /* Round down to the next integer.  */  return (int) l + (l < 0 ? -1 : 0);}# endif#endifDCHAR_T *VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,	    const FCHAR_T *format, va_list args){  DIRECTIVES d;  arguments a;  if (PRINTF_PARSE (format, &d, &a) < 0)    /* errno is already set.  */    return NULL;#define CLEANUP() \  free (d.dir);								\  if (a.arg)								\    free (a.arg);  if (PRINTF_FETCHARGS (args, &a) < 0)    {      CLEANUP ();      errno = EINVAL;      return NULL;    }  {    size_t buf_neededlength;    TCHAR_T *buf;    TCHAR_T *buf_malloced;    const FCHAR_T *cp;    size_t i;    DIRECTIVE *dp;    /* Output string accumulator.  */    DCHAR_T *result;    size_t allocated;    size_t length;    /* Allocate a small buffer that will hold a directive passed to       sprintf or snprintf.  */    buf_neededlength =      xsum4 (7, d.max_width_length, d.max_precision_length, 6);#if HAVE_ALLOCA    if (buf_neededlength < 4000 / sizeof (TCHAR_T))      {	buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));	buf_malloced = NULL;      }    else#endif      {	size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));	if (size_overflow_p (buf_memsize))	  goto out_of_memory_1;	buf = (TCHAR_T *) malloc (buf_memsize);	if (buf == NULL)	  goto out_of_memory_1;	buf_malloced = buf;      }    if (resultbuf != NULL)      {	result = resultbuf;	allocated = *lengthp;      }    else      {	result = NULL;	allocated = 0;      }    length = 0;    /* Invariants:       result is either == resultbuf or == NULL or malloc-allocated.       If length > 0, then result != NULL.  */    /* Ensures that allocated >= needed.  Aborts through a jump to       out_of_memory if needed is SIZE_MAX or otherwise too big.  */#define ENSURE_ALLOCATION(needed) \    if ((needed) > allocated)						     \      {									     \	size_t memory_size;						     \	DCHAR_T *memory;						     \									     \	allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);	     \	if ((needed) > allocated)					     \	  allocated = (needed);						     \	memory_size = xtimes (allocated, sizeof (DCHAR_T));		     \	if (size_overflow_p (memory_size))				     \	  goto out_of_memory;						     \	if (result == resultbuf || result == NULL)			     \	  memory = (DCHAR_T *) malloc (memory_size);			     \	else								     \	  memory = (DCHAR_T *) realloc (result, memory_size);		     \	if (memory == NULL)						     \	  goto out_of_memory;						     \	if (result == resultbuf && length > 0)				     \	  DCHAR_CPY (memory, result, length);				     \	result = memory;						     \      }    for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)      {	if (cp != dp->dir_start)	  {	    size_t n = dp->dir_start - cp;	    size_t augmented_length = xsum (length, n);	    ENSURE_ALLOCATION (augmented_length);	    /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we	       need that the format string contains only ASCII characters	       if FCHAR_T and DCHAR_T are not the same type.  */	    if (sizeof (FCHAR_T) == sizeof (DCHAR_T))	      {		DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -