Changeset 94255 in vbox for trunk/src/VBox/Runtime/common/string
- Timestamp:
- Mar 15, 2022 10:34:28 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/strformatnum.cpp
r93115 r94255 236 236 237 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, RT_STR_TUPLE("PseudoNan[")) + 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("Nan")); 311 pszTmp = (char *)memcpy(pszTmp, RT_STR_TUPLE("Nan[")) + 4; 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, RT_STR_TUPLE("QNan[")) + 4; 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, RT_STR_TUPLE("[PDn]")) + 5; 344 else 345 pszTmp = (char *)memcpy(pszTmp, RT_STR_TUPLE("[Den]")) + 5; 346 } 347 return rtStrFormatR80CopyOutStr(pszBuf, cbBuf, szTmp, pszTmp - &szTmp[0]); 348 } 349 350 238 351 RTDECL(ssize_t) RTStrFormatR80u2(char *pszBuf, size_t cbBuf, PCRTFLOAT80U2 pr80Value, signed int cchWidth, 239 352 signed int cchPrecision, uint32_t fFlags) 240 353 { 241 NOREF(cchWidth); NOREF(cchPrecision); NOREF(fFlags); 242 char szTmp[160]; 243 244 char *pszTmp = szTmp; 245 if (pr80Value->s.fSign) 246 *pszTmp++ = '-'; 247 else 248 *pszTmp++ = '+'; 249 250 if (pr80Value->s.uExponent == 0) 251 { 354 RT_NOREF(cchWidth, cchPrecision); 252 355 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS 253 if ( !pr80Value->sj64.u63Fraction254 && pr80Value->sj64.fInteger)356 return rtStrFormatR80Worker(pszBuf, cbBuf, pr80Value->sj64.fSign, pr80Value->sj64.fInteger, 357 pr80Value->sj64.u63Fraction, pr80Value->sj64.uExponent, fFlags); 255 358 #else 256 if ( !pr80Value->sj.u32FractionLow257 && !pr80Value->sj.u31FractionHigh258 && pr80Value->sj.fInteger)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); 259 362 #endif 260 *pszTmp++ = '0';261 /* else: Denormal, handled way below. */262 }263 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS264 else if (pr80Value->sj64.uExponent == UINT16_C(0x7fff))265 #else266 else if (pr80Value->sj.uExponent == UINT16_C(0x7fff))267 #endif268 {269 /** @todo Figure out Pseudo inf/nan... */270 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS271 if (pr80Value->sj64.fInteger)272 #else273 if (pr80Value->sj.fInteger)274 #endif275 *pszTmp++ = 'P';276 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS277 if (pr80Value->sj64.u63Fraction == 0)278 #else279 if ( pr80Value->sj.u32FractionLow == 0280 && pr80Value->sj.u31FractionHigh == 0)281 #endif282 {283 *pszTmp++ = 'I';284 *pszTmp++ = 'n';285 *pszTmp++ = 'f';286 }287 else288 {289 *pszTmp++ = 'N';290 *pszTmp++ = 'a';291 *pszTmp++ = 'N';292 }293 }294 if (pszTmp != &szTmp[1])295 *pszTmp = '\0';296 else297 {298 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS299 *pszTmp++ = pr80Value->sj64.fInteger ? '1' : '0';300 #else301 *pszTmp++ = pr80Value->sj.fInteger ? '1' : '0';302 #endif303 *pszTmp++ = 'm';304 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS305 pszTmp += RTStrFormatNumber(pszTmp, pr80Value->sj64.u63Fraction, 16, 2+16, 0,306 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);307 #else308 pszTmp += RTStrFormatNumber(pszTmp, RT_MAKE_U64(pr80Value->sj.u32FractionLow, pr80Value->sj.u31FractionHigh), 16, 2+16, 0,309 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);310 #endif311 312 *pszTmp++ = 'e';313 #ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS314 pszTmp += RTStrFormatNumber(pszTmp, (int32_t)pr80Value->sj64.uExponent - 16383, 10, 0, 0,315 RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);316 #else317 pszTmp += RTStrFormatNumber(pszTmp, (int32_t)pr80Value->sj.uExponent - 16383, 10, 0, 0,318 RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);319 #endif320 }321 322 /*323 * Copy out the result.324 */325 ssize_t cchRet = pszTmp - &szTmp[0];326 if ((size_t)cchRet < cbBuf)327 memcpy(pszBuf, szTmp, cchRet + 1);328 else329 {330 if (cbBuf)331 {332 memcpy(pszBuf, szTmp, cbBuf - 1);333 pszBuf[cbBuf - 1] = '\0';334 }335 cchRet = VERR_BUFFER_OVERFLOW;336 }337 return cchRet;338 363 } 339 364 … … 342 367 signed int cchPrecision, uint32_t fFlags) 343 368 { 344 RTFLOAT80U2 r80ValueU2; 345 RT_ZERO(r80ValueU2); 346 r80ValueU2.s.fSign = pr80Value->s.fSign; 347 r80ValueU2.s.uExponent = pr80Value->s.uExponent; 348 r80ValueU2.s.u64Mantissa = pr80Value->s.u64Mantissa; 349 return RTStrFormatR80u2(pszBuf, cbBuf, &r80ValueU2, cchWidth, cchPrecision, fFlags); 350 } 351 369 RT_NOREF(cchWidth, cchPrecision); 370 return rtStrFormatR80Worker(pszBuf, cbBuf, pr80Value->s.fSign, pr80Value->s.u64Mantissa >> 63, 371 pr80Value->s.u64Mantissa & (RT_BIT_64(63) - 1), pr80Value->s.uExponent, fFlags); 372 } 373
Note:
See TracChangeset
for help on using the changeset viewer.