// // Floating point // static void FmtFloat(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const eFmtLengths & oFmtLengths, const CHAR_8 chExponentSymbol, const eFmtSpecifier & oFmtSpecifier, INT_32 iWidth, INT_32 iPrecision, CHAR_8 chPadSymbol) { using namespace CTPP; /* * fF The double argument is rounded and converted to decimal notation * in the style [-]ddd.ddd, where the number of digits after the * decimal-point character is equal to the precision specification. * If the precision is missing, it is taken as 6; if the precision * is explicitly zero, no decimal-point character appears. If a * decimal point appears, at least one digit appears before it. * * gG The double argument is converted in style f or e (or F or E for G * conversions). The precision specifies the number of significant * digits. If the precision is missing, 6 digits are given; if the * precision is zero, it is treated as 1. Style e is used if the * exponent from its conversion is less than -4 or greater than or * equal to the precision. Trailing zeros are removed from the * fractional part of the result; a decimal point appears only if it * is followed by at least one digit. */ // if (iWidth == -1) { iWidth = 6; } INT_32 iMode; INT_32 iExponent = 0; INT_32 iSign = 0; CHAR_P szEnd = NULL; INT_32 iFormatPrecision; if (oFmtSpecifier == F_FLOAT_F) { iMode = 3; if (iPrecision == -1) { iPrecision = 6; } iFormatPrecision = iPrecision; } // Only one decision left else /* if (oFmtSpecifier == F_FLOAT_G) */ { iMode = 2; if (iPrecision == -1) { iPrecision = 6; } else if (iPrecision == 0) { iPrecision = 1; } iFormatPrecision = iPrecision + 1; } Bigint *freelist[Kmax+1]; for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; } W_FLOAT dData = oCurrentArgument.GetFloat(); AllocatedBlock * aBlocks = NULL; CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iFormatPrecision, &iExponent, &iSign, &szEnd); bool bIsNegative = iSign < 0; --iExponent; INT_32 iPos = szEnd - szBuffer; // Data length INT_32 iFormattedLength; if (oFmtSpecifier == F_FLOAT_F) { if (iExponent < 0) { iFormattedLength = iPrecision + 2; } else { iFormattedLength = iPrecision + iExponent + 1; } } else /* if (oFmtSpecifier == F_FLOAT_G) */ { /* * Style e is used if the * exponent from its conversion is less than -4 or greater than or * equal to the precision. */ if (iExponent < -4 || iExponent >= iPrecision) { // Free memory freedtoa(&aBlocks); if (iWidth == -1) { iWidth = 6; } FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, chExponentSymbol, iWidth, iPrecision, chPadSymbol); return; } if (iPos > iPrecision) { iPos = iPrecision; } else { iPrecision = iPos; } iFormattedLength = iPrecision; if (iExponent < 0) { iFormattedLength += 1 - iExponent; } } // Sign? if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; } // Right-aligned if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } // Sign if (bIsNegative) { oBuffer.Append(1, '-'); } else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); } else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); } if (oFmtSpecifier == F_FLOAT_F) { // Value if (iExponent < 0) { const INT_32 iChars = iPrecision + iExponent + 1; oBuffer.Append(1, '0'); oBuffer.Append(1, '.'); oBuffer.Append(-iExponent - 1, '0'); if (iChars > iPos) { oBuffer.Append(szBuffer, iPos); oBuffer.Append(iChars - iPos, '0'); } else { oBuffer.Append(szBuffer, iChars); } } else { // Value oBuffer.Append(szBuffer, iExponent + 1); if (iPrecision > 0) { iPos -= iExponent; oBuffer.Append(1, '.'); oBuffer.Append(szBuffer + iExponent + 1, iPos - 1); if (iPrecision + 1 > iPos) { oBuffer.Append(iPrecision - iPos + 1, '0'); } } } } else /* if (oFmtSpecifier == F_FLOAT_G) */ { // Value if (iExponent < 0) { const INT_32 iChars = (iPrecision < iPos) ? iPrecision : iPos; oBuffer.Append(1, '0'); oBuffer.Append(1, '.'); oBuffer.Append(- iExponent - 1, '0'); oBuffer.Append(szBuffer, iChars); } else { oBuffer.Append(szBuffer, iExponent + 1); if (iPos > iExponent + 1) { oBuffer.Append(1, '.'); oBuffer.Append(szBuffer + iExponent + 1, iPrecision - iExponent - 1); } } } // Free memory freedtoa(&aBlocks); // Left-aligned if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } }
// // Scientific // static void FmtSci(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const eFmtLengths & oFmtLengths, const CHAR_8 chExponentSymbol, INT_32 iWidth, INT_32 iPrecision, CHAR_8 chPadSymbol) { using namespace CTPP; /* * eE The double argument is rounded and converted in the style * [-]d.ddde+-dd where there is one digit before the decimal-point * character and the number of digits after it is equal to the pre- * cision; if the precision is missing, it is taken as 6; if the * precision is zero, no decimal-point character appears. An E con- * version uses the letter `E' (rather than `e') to introduce the * exponent. The exponent always contains at least two digits; if * the value is zero, the exponent is 00. */ if (iPrecision == -1) { iPrecision = 6; } if (iWidth == -1) { iWidth = 6; } const INT_32 iMode = 2; INT_32 iExponent = 0; INT_32 iSign = 0; CHAR_P szEnd = NULL; Bigint *freelist[Kmax+1]; for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; } W_FLOAT dData = oCurrentArgument.GetFloat(); AllocatedBlock * aBlocks = NULL; CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iPrecision, &iExponent, &iSign, &szEnd); bool bIsNegative = iSign < 0; --iExponent; // Format Exponent CHAR_8 szExponentBuffer[C_INT_BUFFER_LEN + 1]; szExponentBuffer[C_INT_BUFFER_LEN] = 0; bool bExponentIsNegative = false; // Signed INT_32 iExponentPos = DoFormat<INT_32>(iExponent, 10, szDigitsUc, szExponentBuffer, bExponentIsNegative); // Atleast 2 digits in exponent if (iExponentPos == 1) { iExponentPos = 2; szExponentBuffer[C_INT_BUFFER_LEN - 2] = '0'; } ++iExponentPos; // Add exponent sign szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = bExponentIsNegative ? '-' : '+'; // Add exponent char ++iExponentPos; szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = chExponentSymbol; INT_32 iPos = szEnd - szBuffer; // Data length INT_32 iFormattedLength = iExponentPos + 1; //;// = iPos + iExponentPos + 1; // Precision if (iPrecision > iPos) { //iFormattedLength += (iPrecision - iPos); iFormattedLength += iPrecision; } else { iPos = iPrecision; iFormattedLength += iPos; } // Sign? if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; } // Right-aligned if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } // Sign if (bIsNegative) { oBuffer.Append(1, '-'); } else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); } else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); } // Value oBuffer.Append(szBuffer, 1); oBuffer.Append(1, '.'); oBuffer.Append(szBuffer + 1, iPos - 1); // Free memory freedtoa(&aBlocks); // Zeroes, if need if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); } // Exponent oBuffer.Append(szExponentBuffer + C_INT_BUFFER_LEN - iExponentPos, iExponentPos); // Left-aligned if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } }