VirtualBox

Changeset 94300 in vbox


Ignore:
Timestamp:
Mar 17, 2022 8:51:20 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150577
Message:

IPRT: Added RTStrFormatR64 and RTStrFormatR32 and split out the floating point formatting from strformatnum.cpp. bugref:9898

Location:
trunk
Files:
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/mangling.h

    r94291 r94300  
    22402240# define RTStrFormat                                    RT_MANGLER(RTStrFormat)
    22412241# define RTStrFormatNumber                              RT_MANGLER(RTStrFormatNumber)
     2242# define RTStrFormatR32                                 RT_MANGLER(RTStrFormatR32)
     2243# define RTStrFormatR64                                 RT_MANGLER(RTStrFormatR64)
    22422244# define RTStrFormatR80                                 RT_MANGLER(RTStrFormatR80)
    22432245# define RTStrFormatR80u2                               RT_MANGLER(RTStrFormatR80u2)
  • trunk/include/iprt/string.h

    r93962 r94300  
    19081908                                signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
    19091909
     1910/**
     1911 * Formats an 32-bit extended floating point number.
     1912 *
     1913 * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
     1914 * @param   pszBuf          The output buffer.
     1915 * @param   cbBuf           The size of the output buffer.
     1916 * @param   pr80Value       The value to format.
     1917 * @param   cchWidth        Width.
     1918 * @param   cchPrecision    Precision.
     1919 * @param   fFlags          Flags, RTSTR_F_XXX.
     1920 */
     1921RTDECL(ssize_t) RTStrFormatR32(char *pszBuf, size_t cbBuf, PCRTFLOAT32U pr32Value, signed int cchWidth,
     1922                               signed int cchPrecision, uint32_t fFlags);
     1923
     1924/**
     1925 * Formats an 64-bit extended floating point number.
     1926 *
     1927 * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
     1928 * @param   pszBuf          The output buffer.
     1929 * @param   cbBuf           The size of the output buffer.
     1930 * @param   pr80Value       The value to format.
     1931 * @param   cchWidth        Width.
     1932 * @param   cchPrecision    Precision.
     1933 * @param   fFlags          Flags, RTSTR_F_XXX.
     1934 */
     1935RTDECL(ssize_t) RTStrFormatR64(char *pszBuf, size_t cbBuf, PCRTFLOAT64U pr64Value, signed int cchWidth,
     1936                               signed int cchPrecision, uint32_t fFlags);
    19101937
    19111938/**
  • trunk/src/VBox/Runtime/Makefile.kmk

    r94157 r94300  
    641641        common/string/strformat.cpp \
    642642        common/string/RTStrFormat.cpp \
     643        common/string/strformatfloat.cpp \
    643644        common/string/strformatnum.cpp \
    644645        common/string/strformatrt.cpp \
  • trunk/src/VBox/Runtime/common/string/strformatfloat.cpp

    r94283 r94300  
    11/* $Id$ */
    22/** @file
    3  * IPRT - String Formatter, Single Numbers.
     3 * IPRT - String Formatter, Floating Point Numbers (simple approach).
    44 */
    55
     
    3838
    3939
    40 RTDECL(ssize_t) RTStrFormatU8(char *pszBuf, size_t cbBuf, uint8_t u8Value, unsigned int uiBase,
    41                               signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
    42 {
    43     fFlags &= ~RTSTR_F_BIT_MASK;
    44     fFlags |= RTSTR_F_8BIT;
    45 
    46     ssize_t cchRet;
    47     if (cbBuf >= 64)
    48         cchRet = RTStrFormatNumber(pszBuf, u8Value, uiBase, cchWidth, cchPrecision, fFlags);
    49     else
    50     {
    51         char szTmp[64];
    52         cchRet = RTStrFormatNumber(szTmp, u8Value, uiBase, cchWidth, cchPrecision, fFlags);
    53         if ((size_t)cchRet < cbBuf)
    54             memcpy(pszBuf, szTmp, cchRet + 1);
    55         else
    56         {
    57             if (cbBuf)
    58             {
    59                 memcpy(pszBuf, szTmp, cbBuf - 1);
    60                 pszBuf[cbBuf - 1] = '\0';
    61             }
    62             cchRet = VERR_BUFFER_OVERFLOW;
    63         }
    64     }
    65     return cchRet;
    66 }
    67 
    68 
    69 RTDECL(ssize_t) RTStrFormatU16(char *pszBuf, size_t cbBuf, uint16_t u16Value, unsigned int uiBase,
    70                               signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
    71 {
    72     fFlags &= ~RTSTR_F_BIT_MASK;
    73     fFlags |= RTSTR_F_16BIT;
    74 
    75     ssize_t cchRet;
    76     if (cbBuf >= 64)
    77         cchRet = RTStrFormatNumber(pszBuf, u16Value, uiBase, cchWidth, cchPrecision, fFlags);
    78     else
    79     {
    80         char szTmp[64];
    81         cchRet = RTStrFormatNumber(szTmp, u16Value, uiBase, cchWidth, cchPrecision, fFlags);
    82         if ((size_t)cchRet < cbBuf)
    83             memcpy(pszBuf, szTmp, cchRet + 1);
    84         else
    85         {
    86             if (cbBuf)
    87             {
    88                 memcpy(pszBuf, szTmp, cbBuf - 1);
    89                 pszBuf[cbBuf - 1] = '\0';
    90             }
    91             cchRet = VERR_BUFFER_OVERFLOW;
    92         }
    93     }
    94     return cchRet;
    95 }
    96 
    97 
    98 RTDECL(ssize_t) RTStrFormatU32(char *pszBuf, size_t cbBuf, uint32_t u32Value, unsigned int uiBase,
    99                               signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
    100 {
    101     fFlags &= ~RTSTR_F_BIT_MASK;
    102     fFlags |= RTSTR_F_32BIT;
    103 
    104     ssize_t cchRet;
    105     if (cbBuf >= 64)
    106         cchRet = RTStrFormatNumber(pszBuf, u32Value, uiBase, cchWidth, cchPrecision, fFlags);
    107     else
    108     {
    109         char szTmp[64];
    110         cchRet = RTStrFormatNumber(szTmp, u32Value, uiBase, cchWidth, cchPrecision, fFlags);
    111         if ((size_t)cchRet < cbBuf)
    112             memcpy(pszBuf, szTmp, cchRet + 1);
    113         else
    114         {
    115             if (cbBuf)
    116             {
    117                 memcpy(pszBuf, szTmp, cbBuf - 1);
    118                 pszBuf[cbBuf - 1] = '\0';
    119             }
    120             cchRet = VERR_BUFFER_OVERFLOW;
    121         }
    122     }
    123     return cchRet;
    124 }
    125 
    126 
    127 RTDECL(ssize_t) RTStrFormatU64(char *pszBuf, size_t cbBuf, uint64_t u64Value, unsigned int uiBase,
    128                               signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
    129 {
    130     fFlags &= ~RTSTR_F_BIT_MASK;
    131     fFlags |= RTSTR_F_64BIT;
    132 
    133     ssize_t cchRet;
    134     if (cbBuf >= 64)
    135         cchRet = RTStrFormatNumber(pszBuf, u64Value, uiBase, cchWidth, cchPrecision, fFlags);
    136     else
    137     {
    138         char szTmp[64];
    139         cchRet = RTStrFormatNumber(szTmp, u64Value, uiBase, cchWidth, cchPrecision, fFlags);
    140         if ((size_t)cchRet < cbBuf)
    141             memcpy(pszBuf, szTmp, cchRet + 1);
    142         else
    143         {
    144             if (cbBuf)
    145             {
    146                 memcpy(pszBuf, szTmp, cbBuf - 1);
    147                 pszBuf[cbBuf - 1] = '\0';
    148             }
    149             cchRet = VERR_BUFFER_OVERFLOW;
    150         }
    151     }
    152     return cchRet;
    153 }
    154 
    155 
    156 RTDECL(ssize_t) RTStrFormatU128(char *pszBuf, size_t cbBuf, PCRTUINT128U pu128, unsigned int uiBase,
    157                                 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
    158 {
    159     NOREF(cchWidth); NOREF(cchPrecision);
    160     if (uiBase != 16)
    161         fFlags |= RTSTR_F_SPECIAL;
    162     fFlags &= ~RTSTR_F_BIT_MASK;
    163 
    164     char szTmp[64+32+32+32];
    165     char *pszTmp = cbBuf >= sizeof(szTmp) ? pszBuf : szTmp;
    166     size_t cchResult = RTStrFormatNumber(pszTmp, pu128->QWords.qw1, 16, 0, 0, fFlags | RTSTR_F_64BIT);
    167     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu128->QWords.qw0, 16, 8, 0,
    168                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    169     if (pszTmp == pszBuf)
    170         return cchResult;
    171     int rc = RTStrCopy(pszBuf, cbBuf, pszTmp);
    172     if (RT_SUCCESS(rc))
    173         return cchResult;
    174     return rc;
    175 }
    176 
    177 
    178 RTDECL(ssize_t) RTStrFormatU256(char *pszBuf, size_t cbBuf, PCRTUINT256U pu256, unsigned int uiBase,
    179                                 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
    180 {
    181     NOREF(cchWidth); NOREF(cchPrecision);
    182     if (uiBase != 16)
    183         fFlags |= RTSTR_F_SPECIAL;
    184     fFlags &= ~RTSTR_F_BIT_MASK;
    185 
    186     char szTmp[64+32+32+32];
    187     char *pszTmp = cbBuf >= sizeof(szTmp) ? pszBuf : szTmp;
    188     size_t cchResult = RTStrFormatNumber(pszTmp, pu256->QWords.qw3, 16, 0, 0, fFlags | RTSTR_F_64BIT);
    189     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu256->QWords.qw2, 16, 8, 0,
    190                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    191     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu256->QWords.qw1, 16, 8, 0,
    192                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    193     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu256->QWords.qw0, 16, 8, 0,
    194                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    195     if (pszTmp == pszBuf)
    196         return cchResult;
    197     int rc = RTStrCopy(pszBuf, cbBuf, pszTmp);
    198     if (RT_SUCCESS(rc))
    199         return cchResult;
    200     return rc;
    201 }
    202 
    203 
    204 RTDECL(ssize_t) RTStrFormatU512(char *pszBuf, size_t cbBuf, PCRTUINT512U pu512, unsigned int uiBase,
    205                                 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
    206 {
    207     NOREF(cchWidth); NOREF(cchPrecision);
    208     if (uiBase != 16)
    209         fFlags |= RTSTR_F_SPECIAL;
    210     fFlags &= ~RTSTR_F_BIT_MASK;
    211 
    212     char szTmp[64+32+32+32 + 32+32+32+32];
    213     char *pszTmp = cbBuf >= sizeof(szTmp) ? pszBuf : szTmp;
    214     size_t cchResult = RTStrFormatNumber(pszTmp, pu512->QWords.qw7, 16, 0, 0, fFlags | RTSTR_F_64BIT);
    215     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw6, 16, 8, 0,
    216                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    217     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw5, 16, 8, 0,
    218                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    219     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw4, 16, 8, 0,
    220                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    221     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw3, 16, 8, 0,
    222                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    223     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw2, 16, 8, 0,
    224                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    225     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw1, 16, 8, 0,
    226                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    227     cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw0, 16, 8, 0,
    228                                    (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
    229     if (pszTmp == pszBuf)
    230         return cchResult;
    231     int rc = RTStrCopy(pszBuf, cbBuf, pszTmp);
    232     if (RT_SUCCESS(rc))
    233         return cchResult;
    234     return rc;
    235 }
    236 
    237 
    23840/**
    23941 * Helper for rtStrFormatR80Worker that copies out the resulting string.
    24042 */
    241 static ssize_t rtStrFormatR80CopyOutStr(char *pszBuf, size_t cbBuf, const char *pszSrc, size_t cchSrc)
     43static ssize_t rtStrFormatCopyOutStr(char *pszBuf, size_t cbBuf, const char *pszSrc, size_t cchSrc)
    24244{
    24345    if (cchSrc < cbBuf)
     
    25355    }
    25456    return VERR_BUFFER_OVERFLOW;
     57}
     58
     59
     60RTDECL(ssize_t) RTStrFormatR32(char *pszBuf, size_t cbBuf, PCRTFLOAT32U pr32Value, signed int cchWidth,
     61                               signed int cchPrecision, uint32_t fFlags)
     62{
     63    RT_NOREF(cchWidth, cchPrecision);
     64
     65    /*
     66     * Handle some special values that does require any value annotating.
     67     */
     68    bool const fSign = pr32Value->s.fSign;
     69    if (RTFLOAT32U_IS_ZERO(pr32Value))
     70        return fSign
     71             ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+0"))
     72             : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-0"));
     73    if (RTFLOAT32U_IS_INF(pr32Value))
     74        return fSign
     75             ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Inf"))
     76             : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Inf"));
     77
     78    /*
     79     * Output sign first.
     80     */
     81    char  szTmp[80];
     82    char *pszTmp = szTmp;
     83    if (fSign)
     84        *pszTmp++ = '-';
     85    else
     86        *pszTmp++ = '+';
     87
     88    /*
     89     * Normal?
     90     */
     91    uint16_t const uExponent = pr32Value->s.uExponent;
     92    uint32_t const uFraction = pr32Value->s.uFraction;
     93    if (RTFLOAT32U_IS_NORMAL(pr32Value))
     94    {
     95        *pszTmp++ = '1';
     96        *pszTmp++ = 'm';
     97        pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + (RTFLOAT32U_FRACTION_BITS + 3) / 4, 0,
     98                                    RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_32BIT);
     99
     100        *pszTmp++ = '^';
     101        pszTmp += RTStrFormatNumber(pszTmp, (int32_t)uExponent - RTFLOAT32U_EXP_BIAS, 10, 0, 0,
     102                                    RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
     103    }
     104    /*
     105     * Subnormal?
     106     */
     107    else if (RTFLOAT32U_IS_SUBNORMAL(pr32Value))
     108    {
     109        *pszTmp++ = '0';
     110        *pszTmp++ = 'm';
     111        pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + (RTFLOAT32U_FRACTION_BITS + 3) / 4, 0,
     112                                    RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_32BIT);
     113        if (fFlags & RTSTR_F_SPECIAL)
     114            pszTmp = (char *)memcpy(pszTmp, "[SubN]", 6) + 6;
     115    }
     116    /*
     117     * NaN.
     118     */
     119    else
     120    {
     121        Assert(RTFLOAT32U_IS_NAN(pr32Value));
     122        if (!(fFlags & RTSTR_F_SPECIAL))
     123            return rtStrFormatCopyOutStr(pszBuf, cbBuf,
     124                                         RTFLOAT32U_IS_SIGNALLING_NAN(pr32Value)
     125                                         ? (fSign ? "-SNan[" : "+SNan[") : fSign ? "-QNan[" : "+QNan[", 5);
     126        *pszTmp++ = RTFLOAT32U_IS_SIGNALLING_NAN(pr32Value) ? 'S' : 'Q';
     127        *pszTmp++ = 'N';
     128        *pszTmp++ = 'a';
     129        *pszTmp++ = 'N';
     130        *pszTmp++ = '[';
     131        *pszTmp++ = '.';
     132        pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + (RTFLOAT32U_FRACTION_BITS + 3) / 4, 0,
     133                                    RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_32BIT);
     134        *pszTmp++ = ']';
     135    }
     136    return rtStrFormatCopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
     137}
     138
     139
     140
     141
     142RTDECL(ssize_t) RTStrFormatR64(char *pszBuf, size_t cbBuf, PCRTFLOAT64U pr64Value, signed int cchWidth,
     143                               signed int cchPrecision, uint32_t fFlags)
     144{
     145    RT_NOREF(cchWidth, cchPrecision);
     146
     147    /*
     148     * Handle some special values that does require any value annotating.
     149     */
     150    bool const fSign = pr64Value->s.fSign;
     151    if (RTFLOAT64U_IS_ZERO(pr64Value))
     152        return fSign
     153             ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+0"))
     154             : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-0"));
     155    if (RTFLOAT64U_IS_INF(pr64Value))
     156        return fSign
     157             ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Inf"))
     158             : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Inf"));
     159
     160    /*
     161     * Output sign first.
     162     */
     163    char  szTmp[160];
     164    char *pszTmp = szTmp;
     165    if (fSign)
     166        *pszTmp++ = '-';
     167    else
     168        *pszTmp++ = '+';
     169
     170    /*
     171     * Normal?
     172     */
     173    uint16_t const uExponent = pr64Value->s.uExponent;
     174    uint64_t const uFraction = RT_MAKE_U64(pr64Value->s.uFractionLow, pr64Value->s.uFractionHigh);
     175    if (RTFLOAT64U_IS_NORMAL(pr64Value))
     176    {
     177        *pszTmp++ = '1';
     178        *pszTmp++ = 'm';
     179        pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT64U_FRACTION_BITS / 4, 0,
     180                                    RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
     181
     182        *pszTmp++ = '^';
     183        pszTmp += RTStrFormatNumber(pszTmp, (int32_t)uExponent - RTFLOAT64U_EXP_BIAS, 10, 0, 0,
     184                                    RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
     185    }
     186    /*
     187     * Subnormal?
     188     */
     189    else if (RTFLOAT64U_IS_SUBNORMAL(pr64Value))
     190    {
     191        *pszTmp++ = '0';
     192        *pszTmp++ = 'm';
     193        pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT64U_FRACTION_BITS / 4, 0,
     194                                    RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
     195        if (fFlags & RTSTR_F_SPECIAL)
     196            pszTmp = (char *)memcpy(pszTmp, "[SubN]", 6) + 6;
     197    }
     198    /*
     199     * NaN.
     200     */
     201    else
     202    {
     203        Assert(RTFLOAT64U_IS_NAN(pr64Value));
     204        if (!(fFlags & RTSTR_F_SPECIAL))
     205            return rtStrFormatCopyOutStr(pszBuf, cbBuf,
     206                                         RTFLOAT64U_IS_SIGNALLING_NAN(pr64Value)
     207                                         ? (fSign ? "-SNan[" : "+SNan[") : fSign ? "-QNan[" : "+QNan[", 5);
     208        *pszTmp++ = RTFLOAT64U_IS_SIGNALLING_NAN(pr64Value) ? 'S' : 'Q';
     209        *pszTmp++ = 'N';
     210        *pszTmp++ = 'a';
     211        *pszTmp++ = 'N';
     212        *pszTmp++ = '[';
     213        *pszTmp++ = '.';
     214        pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT64U_FRACTION_BITS / 4, 0,
     215                                    RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
     216        *pszTmp++ = ']';
     217    }
     218    return rtStrFormatCopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
    255219}
    256220
     
    283247            && !fInteger)
    284248            return fSign
    285                  ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+0"))
    286                  : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-0"));
     249                 ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+0"))
     250                 : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-0"));
    287251        fDenormal = true;
    288252    }
    289     else if (uExponent == UINT16_C(0x7fff))
     253    else if (uExponent == RTFLOAT64U_EXP_MAX)
    290254    {
    291255        if (!fInteger)
     
    293257            if (!uFraction)
    294258                return fSign
    295                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+PseudoInf"))
    296                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-PseudoInf"));
     259                     ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+PseudoInf"))
     260                     : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-PseudoInf"));
    297261            if (!(fFlags & RTSTR_F_SPECIAL))
    298262                return fSign
    299                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+PseudoNan"))
    300                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-PseudoNan"));
     263                     ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+PseudoNan"))
     264                     : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-PseudoNan"));
    301265            pszTmp = (char *)memcpy(pszTmp, "PseudoNan[", 10) + 10;
    302266        }
     
    305269            if (!(uFraction & (RT_BIT_64(62) - 1)))
    306270                return fSign
    307                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Inf"))
    308                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Inf"));
     271                     ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Inf"))
     272                     : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Inf"));
    309273            if (!(fFlags & RTSTR_F_SPECIAL))
    310                 return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("SNan"));
     274                return rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("SNan"));
    311275            pszTmp = (char *)memcpy(pszTmp, "SNan[", 5) + 5;
    312276        }
     
    315279            if (!(uFraction & (RT_BIT_64(62) - 1)))
    316280                return fSign
    317                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Ind"))
    318                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Ind"));
     281                     ? rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Ind"))
     282                     : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Ind"));
    319283            if (!(fFlags & RTSTR_F_SPECIAL))
    320                 return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("QNan"));
     284                return rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("QNan"));
    321285            pszTmp = (char *)memcpy(pszTmp, "QNan[", 5) + 5;
    322286        }
    323         pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + 16, 0,
     287        pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT64U_FRACTION_BITS / 4, 0,
    324288                                    RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
    325289        *pszTmp++ = ']';
    326         return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
     290        return rtStrFormatCopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
    327291    }
    328292
     
    332296    *pszTmp++ = fInteger ? '1' : '0';
    333297    *pszTmp++ = 'm';
    334     pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2+16, 0,
     298    pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT64U_FRACTION_BITS / 4, 0,
    335299                                RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
    336300
    337301    *pszTmp++ = '^';
    338     pszTmp += RTStrFormatNumber(pszTmp, (int32_t)uExponent - 16383, 10, 0, 0,
     302    pszTmp += RTStrFormatNumber(pszTmp, (int32_t)uExponent - RTFLOAT64U_EXP_BIAS, 10, 0, 0,
    339303                                RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
    340304    if (fDenormal && (fFlags & RTSTR_F_SPECIAL))
     
    345309            pszTmp = (char *)memcpy(pszTmp, "[Den]", 5) + 5;
    346310    }
    347     return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
     311    return rtStrFormatCopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
    348312}
    349313
  • trunk/src/VBox/Runtime/common/string/strformatnum.cpp

    r94283 r94300  
    235235}
    236236
    237 
    238 /**
    239  * Helper for rtStrFormatR80Worker that copies out the resulting string.
    240  */
    241 static ssize_t rtStrFormatR80CopyOutStr(char *pszBuf, size_t cbBuf, const char *pszSrc, size_t cchSrc)
    242 {
    243     if (cchSrc < cbBuf)
    244     {
    245         memcpy(pszBuf, pszSrc, cchSrc);
    246         pszBuf[cchSrc] = '\0';
    247         return cchSrc;
    248     }
    249     if (cbBuf)
    250     {
    251         memcpy(pszBuf, pszSrc, cbBuf - 1);
    252         pszBuf[cbBuf - 1] = '\0';
    253     }
    254     return VERR_BUFFER_OVERFLOW;
    255 }
    256 
    257 
    258 /**
    259  * Common worker for RTStrFormatR80 and RTStrFormatR80u2.
    260  */
    261 static ssize_t rtStrFormatR80Worker(char *pszBuf, size_t cbBuf, bool const fSign, bool const fInteger,
    262                                     uint64_t const uFraction, uint16_t const uExponent, uint32_t fFlags)
    263 {
    264     char szTmp[160];
    265 
    266     /*
    267      * Output sign first.
    268      */
    269     char *pszTmp = szTmp;
    270     if (fSign)
    271         *pszTmp++ = '-';
    272     else
    273         *pszTmp++ = '+';
    274 
    275     /*
    276      * Then check for special numbers (indicated by expontent).
    277      */
    278     bool fDenormal = false;
    279     if (uExponent == 0)
    280     {
    281         /* Zero? */
    282         if (   !uFraction
    283             && !fInteger)
    284             return fSign
    285                  ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+0"))
    286                  : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-0"));
    287         fDenormal = true;
    288     }
    289     else if (uExponent == UINT16_C(0x7fff))
    290     {
    291         if (!fInteger)
    292         {
    293             if (!uFraction)
    294                 return fSign
    295                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+PseudoInf"))
    296                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-PseudoInf"));
    297             if (!(fFlags & RTSTR_F_SPECIAL))
    298                 return fSign
    299                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+PseudoNan"))
    300                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-PseudoNan"));
    301             pszTmp = (char *)memcpy(pszTmp, "PseudoNan[", 10) + 10;
    302         }
    303         else if (!(uFraction & RT_BIT_64(62)))
    304         {
    305             if (!(uFraction & (RT_BIT_64(62) - 1)))
    306                 return fSign
    307                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Inf"))
    308                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Inf"));
    309             if (!(fFlags & RTSTR_F_SPECIAL))
    310                 return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("SNan"));
    311             pszTmp = (char *)memcpy(pszTmp, "SNan[", 5) + 5;
    312         }
    313         else
    314         {
    315             if (!(uFraction & (RT_BIT_64(62) - 1)))
    316                 return fSign
    317                      ? rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+Ind"))
    318                      : rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("-Ind"));
    319             if (!(fFlags & RTSTR_F_SPECIAL))
    320                 return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("QNan"));
    321             pszTmp = (char *)memcpy(pszTmp, "QNan[", 5) + 5;
    322         }
    323         pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + 16, 0,
    324                                     RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
    325         *pszTmp++ = ']';
    326         return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
    327     }
    328 
    329     /*
    330      * Format the mantissa and exponent.
    331      */
    332     *pszTmp++ = fInteger ? '1' : '0';
    333     *pszTmp++ = 'm';
    334     pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2+16, 0,
    335                                 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
    336 
    337     *pszTmp++ = '^';
    338     pszTmp += RTStrFormatNumber(pszTmp, (int32_t)uExponent - 16383, 10, 0, 0,
    339                                 RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
    340     if (fDenormal && (fFlags & RTSTR_F_SPECIAL))
    341     {
    342         if (fInteger)
    343             pszTmp = (char *)memcpy(pszTmp, "[PDn]", 5) + 5;
    344         else
    345             pszTmp = (char *)memcpy(pszTmp, "[Den]", 5) + 5;
    346     }
    347     return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]);
    348 }
    349 
    350 
    351 RTDECL(ssize_t) RTStrFormatR80u2(char *pszBuf, size_t cbBuf, PCRTFLOAT80U2 pr80Value, signed int cchWidth,
    352                                  signed int cchPrecision, uint32_t fFlags)
    353 {
    354     RT_NOREF(cchWidth, cchPrecision);
    355 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
    356     return rtStrFormatR80Worker(pszBuf, cbBuf, pr80Value->sj64.fSign, pr80Value->sj64.fInteger,
    357                                 pr80Value->sj64.uFraction, pr80Value->sj64.uExponent, fFlags);
    358 #else
    359     return rtStrFormatR80Worker(pszBuf, cbBuf, pr80Value->sj.fSign, pr80Value->sj.fInteger,
    360                                 RT_MAKE_U64(pr80Value->sj.u32FractionLow, pr80Value->sj.u31FractionHigh),
    361                                 pr80Value->sj.uExponent, fFlags);
    362 #endif
    363 }
    364 
    365 
    366 RTDECL(ssize_t) RTStrFormatR80(char *pszBuf, size_t cbBuf, PCRTFLOAT80U pr80Value, signed int cchWidth,
    367                                signed int cchPrecision, uint32_t fFlags)
    368 {
    369     RT_NOREF(cchWidth, cchPrecision);
    370     return rtStrFormatR80Worker(pszBuf, cbBuf, pr80Value->s.fSign, pr80Value->s.uMantissa >> 63,
    371                                 pr80Value->s.uMantissa & (RT_BIT_64(63) - 1), pr80Value->s.uExponent, fFlags);
    372 }
    373 
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette