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

📄 snprintf.c

📁 一个Windows下的Linux专用虚拟机
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (numbersigned)    {        if (number < 0)        {            /* Deal with negativity */            sign = '-';            number = -number;        }        else if (flags & FLAG_SIGNED)        {            sign = '+';        }        else if (flags & FLAG_SIGN_PAD)        {            sign = ' ';        }    }    /* Create number */    if (numbersigned)    {        if (number == 0)            iszero = 1;        do        {            PUSH(number % base);            number /= base;            len++;        } while (number != 0);    }    else    {        if (unumber == 0)            iszero = 1;        do        {            PUSH(unumber % base);            unumber /= base;            len++;        } while (unumber != 0);    }    /* Octal hash character (alternate form) */    if (fmt == 'o' && (flags & FLAG_HASH) && precision <= len &&        precision != 0 && !iszero )    {        precision = len + 1;    }    /* Determine width of sign, if any. */    if ( (fmt == 'x' || fmt == 'X') && (flags & FLAG_HASH) && !iszero )        addprefix = 2;    else if (sign != 0)        addprefix = 1;    /* Make up precision (zero pad on left) */    while (len < precision)    {        PUSH(0);        len++;    }    if (len + addprefix < width)    {        totallen = width;        widthpad = width - (len + addprefix);    }    else        totallen = len + addprefix;    if (*nmax <= 1)        return totallen;    /* Write sign or "0x" */    if (flags & FLAG_ZERO_PAD)    {        if (addprefix == 2) /* 0x */        {            if (*nmax > 1)            {                **pinsertion = '0';                *pinsertion += 1;                *nmax -= 1;            }            if (*nmax > 1)            {                **pinsertion = fmt;                *pinsertion += 1;                *nmax -= 1;            }        }        else if (addprefix == 1) /* sign */        {            if (*nmax > 1)            {                **pinsertion = sign;                *pinsertion += 1;                *nmax -= 1;            }        }    }    /* Width pad */    if ( !(flags & FLAG_LEFT_ALIGN) )    {        if (*nmax <= 1)            widthpad = 0;        else if ((int) *nmax + 1 < widthpad)            widthpad = *nmax - 1;        if (flags & FLAG_ZERO_PAD)            memset(*pinsertion, '0', widthpad);        else            memset(*pinsertion, ' ', widthpad);        *pinsertion += widthpad;        *nmax -= widthpad;    }    /* Write sign or "0x" */    if ( !(flags & FLAG_ZERO_PAD) )    {        if (addprefix == 2) /* 0x */        {            if (*nmax > 1)            {                **pinsertion = '0';                *pinsertion += 1;                *nmax -= 1;            }            if (*nmax > 1)            {                **pinsertion = fmt;                *pinsertion += 1;                *nmax -= 1;            }        }        else if (addprefix == 1) /* sign */        {            if (*nmax > 1)            {                **pinsertion = sign;                *pinsertion += 1;                *nmax -= 1;            }        }    }    /* Write number */    if (*nmax <= 1)        len = 0;    else if ((int) *nmax + 1 < len)        len = *nmax - 1;    for (; len > 0; len--)    {        char n = POP();        if (n <= 9)        {            **pinsertion = n + '0';            *pinsertion += 1;        }        else        {            **pinsertion = n - 10 + char10;            *pinsertion += 1;        }    }    *nmax -= len;    if (flags & FLAG_LEFT_ALIGN)    {        if (*nmax <= 1)            widthpad = 0;        else if ((int) *nmax + 1 < widthpad)            widthpad = *nmax - 1;        memset(*pinsertion, ' ', widthpad);        *pinsertion += widthpad;        *nmax -= widthpad;    }    return totallen;}/* * WARNING: Assumes 32 bit longs and 64 bit doubles */typedef union {    double D;    struct {        unsigned long W0;        unsigned long W1;    };} DBLBITS;#define EXP_MASK  0x7FF00000#define SIGN_MASK 0x80000000#define MANTISSA_MASK ~(SIGN_MASK | EXP_MASK)#define QNAN_MASK 0x00080000 /* first bit of mantissa */#ifdef SNPRINTF_FLOAT/* These functions not defined on all platforms, so * do the checks manually * WARNING: Assumes 64-bit IEEE representation *    (so it won't run on your Cray :) */#define ISNAN(x) \    ( (((DBLBITS *) &x)->W1 & EXP_MASK) == EXP_MASK \  && ((((DBLBITS *) &x)->W1 & MANTISSA_MASK) != 0 || ((DBLBITS *) &x)->W0 != 0) )#define ISQNAN(x) \    ( ISNAN(x) && (((DBLBITS *) &x)->W1 & QNAN_MASK) )#define ISSNAN(x) \    ( ISNAN(x) && !ISQNAN(x) )#define ISINF(x) \   ( (((DBLBITS *) &x)->W1 & EXP_MASK) == EXP_MASK \  && ((((DBLBITS *) &x)->W1 & MANTISSA_MASK) == 0 && ((DBLBITS *) &x)->W0 == 0) )/* Format a double-precision float into the buffer.  Parameters: *   *&pinsertion   Reference to pointer to buffer (can be reference to NULL) *   &nmax          Reference to size of buffer.  This is may be modified *   fmt            Format character (one of "eEfgG") *   flags          0 or combination of flags (see .h file for #defines) *   width          Width of double, as defined in printf *   precision      Precision of double, as defined in printf *   ap             Argument list */static int pvsnfmt_double(char **pinsertion, long *nmax, const char fmt, int flags,                int width, int precision, char prefix, va_list *ap){    char *digits;    int sign = 0;    int dec;    double value = va_arg(*ap, double);    int len;    int pad = 0;    int signwidth = 0;    int totallen;    char signchar = 0;    int leadingzeros = 0;    int printdigits; /* temporary var used in different contexts */    /* Check for special values first */    char *special = 0;    if (ISSNAN(value))        special = "NaN";    else if (ISQNAN(value))        special = "NaN";    else if ( ISINF(value) )    {        if (value < 0)            sign = 1;        special = "Inf";    }    if (special)    {        totallen = len = co_strlen(special);        /* Sign (this is silly for NaN but conforming to printf */        if (flags & (FLAG_SIGNED | FLAG_SIGN_PAD) || sign)        {            if (sign)                signchar = '-';            else if (flags & FLAG_SIGN_PAD)                signchar = ' ';            else                signchar = '+';            totallen++;        }        /* Padding */        if (totallen < width)            pad = width - totallen;        else            pad = 0;        totallen += pad ;        /* Sign now if zeropad */        if (flags & FLAG_ZERO_PAD && signchar)        {            if (*nmax > 1)            {                **pinsertion = signchar;                *pinsertion += 1;                *nmax -= 1;            }        }        /* Right align */        if ( !(flags & FLAG_LEFT_ALIGN) )        {            if (*nmax <= 1)                pad  = 0;            else if ((int) *nmax - 1 < pad )                pad  = *nmax - 1;            if (flags & FLAG_ZERO_PAD)                memset(*pinsertion, '0', pad );            else                memset(*pinsertion, ' ', pad );            *pinsertion += pad ;            *nmax -= pad ;        }        /* Sign now if not zeropad */        if (!(flags & FLAG_ZERO_PAD) && signchar)        {            if (*nmax > 1)            {                **pinsertion = signchar;                *pinsertion += 1;                *nmax -= 1;            }        }        if (*nmax <= 0)            len = 0;        else if ((int) *nmax - 1 < len)            len = *nmax - 1;        memcpy(*pinsertion, special, len);        *pinsertion += len;        *nmax -= len;        /* Left align */        if (flags & FLAG_LEFT_ALIGN)        {            if (*nmax <= 1)                pad  = 0;            else if ((int) *nmax - 1 < pad )                pad  = *nmax - 1;            memset(*pinsertion, ' ', pad );            *pinsertion += pad ;            *nmax -= pad ;        }        return totallen;    }    if (fmt == 'f')    {        if (precision == UNKNOWN_PRECISION)            precision = 6;        digits = FCVT(value, precision, &dec, &sign);        len = co_strlen(digits);        if (dec > 0)            totallen = dec;        else            totallen = 0;        /* plus 1 for decimal place */
        if (dec <= 0)            totallen += 2; /* and trailing ".0" */        else if (precision > 0 || flags & FLAG_HASH)            totallen += 1;
        /* Determine sign width (0 or 1) */        if (flags & (FLAG_SIGNED | FLAG_SIGN_PAD) || sign)        {            if (sign)                signchar = '-';            else if (flags & FLAG_SIGN_PAD)                signchar = ' ';            else                signchar = '+';            totallen++;        }        /* Determine if leading zeros required */        if (dec <= 0)        {            leadingzeros = 1 - dec; /* add one for zero before decimal point (0.) */        }        if (leadingzeros - 1 > precision)            totallen += precision;        else if (len - dec > 0)            totallen += precision;        else            totallen += leadingzeros;        /* Determine padding width */        if (totallen < width)            pad = width - totallen;        totallen += pad;        if (*nmax <= 1)            return totallen;        /* Now that the length has been calculated, print as much of it         * as possible into the buffer         */        /* Print sign now if padding with zeros */        if (flags & FLAG_ZERO_PAD && signchar != 0)        {            if (*nmax > 1)            {                **pinsertion = signchar;                *pinsertion += 1;                *nmax -= 1;            }        }        /* Print width padding if right-aligned */        if ( !(flags & FLAG_LEFT_ALIGN) )        {            if (*nmax <= 1)                pad = 0;            else if ((int) *nmax - 1 < pad)                pad = *nmax - 1;            if (flags & FLAG_ZERO_PAD)                memset(*pinsertion, '0', pad);            else                memset(*pinsertion, ' ', pad);            *pinsertion += pad;            *nmax -= pad;        }        /* Print sign now if padding was spaces */        if ( !(flags & FLAG_ZERO_PAD) && signchar != 0 )        {            **pinsertion = signchar;            *pinsertion += 1;            *nmax -= 1;        }        /* Print leading zeros */        if (leadingzeros)        {            /* Print "0.", then leadingzeros - 1 */            if (*nmax > 1)            {                **pinsertion = '0';                *pinsertion += 1;                *nmax -= 1;            }            if (precision > 0 || flags & FLAG_HASH)            {                if (*nmax > 1)                {                    **pinsertion = '.';                    *pinsertion += 1;                    *nmax -= 1;                }            }            /* WARNING not rounding here!             * i.e. printf(".3f", 0.0007) gives "0.000" not "0.001"             *             * This whole function could do with a rewrite...             */            if (leadingzeros - 1 > precision)            {                leadingzeros = precision + 1;                len = 0;            }            /* END WARNING */            precision -= leadingzeros - 1;            if (*nmax <= 1)                leadingzeros = 0;            else if ((int) *nmax /* - 1 */ < leadingzeros /* -1 */)                leadingzeros = *nmax; /* -1 */            leadingzeros--;            memset(*pinsertion, '0', leadingzeros);            *pinsertion += leadingzeros;            *nmax -= leadingzeros;        }        /* Print digits before decimal place */        if (dec > 0)        {            if (*nmax <= 1)                printdigits = 0;            else if ((int) *nmax - 1 < dec)                printdigits = *nmax - 1;            else                printdigits = dec;            memcpy(*pinsertion, digits, printdigits);            *pinsertion += printdigits;            *nmax -= printdigits;            if (precision > 0 || flags & FLAG_HASH)            {                /* Print decimal place */                if (*nmax > 1)                {                    **pinsertion = '.';                    *pinsertion += 1;                    *nmax -= 1;                }                /* Print trailing zero if no precision but hash given */                if (precision == 0 && *nmax > 1)                {                    **pinsertion = '0';                    *pinsertion += 1;                    *nmax -= 1;                }            }            /* Bypass the digits we've already printed */            len -= dec;            digits += dec;        }        /* Print digits after decimal place */        if (len > precision)            len = precision;        if (*nmax <= 1)            printdigits = 0;        else if ((int) *nmax - 1 < len)            printdigits = *nmax - 1;        else            printdigits = len;        memcpy(*pinsertion, digits, printdigits);        *pinsertion += printdigits;        *nmax -= printdigits;        /* Print left-aligned pad */        if (flags & FLAG_LEFT_ALIGN)        {            if (*nmax <= 1)                pad = 0;            else if ((int) *nmax - 1 < pad)                pad = *nmax - 1;            memset(*pinsertion, ' ', pad);            *pinsertion += pad;            *nmax -= pad;        }        return totallen;    }    return 0;}#endif

⌨️ 快捷键说明

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