1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <rtl/math.h> 21 22 #include <config_global.h> 23 #include <o3tl/safeint.hxx> 24 #include <osl/diagnose.h> 25 #include <rtl/alloc.h> 26 #include <rtl/character.hxx> 27 #include <rtl/math.hxx> 28 #include <rtl/strbuf.h> 29 #include <rtl/string.h> 30 #include <rtl/ustrbuf.h> 31 #include <rtl/ustring.h> 32 #include <sal/mathconf.h> 33 #include <sal/types.h> 34 35 #include <algorithm> 36 #include <cassert> 37 #include <float.h> 38 #include <limits> 39 #include <limits.h> 40 #include <math.h> 41 #include <memory> 42 #include <stdlib.h> 43 44 #include <dtoa.h> 45 46 #if !HAVE_GCC_BUILTIN_FFS && !defined _WIN32 47 #include <strings.h> 48 #endif 49 50 static int const n10Count = 16; 51 static double const n10s[2][n10Count] = { 52 { 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 53 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16 }, 54 { 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 55 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16 } 56 }; 57 58 // return pow(10.0,nExp) optimized for exponents in the interval [-16,16] 59 static double getN10Exp(int nExp) 60 { 61 if (nExp < 0) 62 { 63 // && -nExp > 0 necessary for std::numeric_limits<int>::min() 64 // because -nExp = nExp 65 if (-nExp <= n10Count && -nExp > 0) 66 return n10s[1][-nExp-1]; 67 return pow(10.0, static_cast<double>(nExp)); 68 } 69 if (nExp > 0) 70 { 71 if (nExp <= n10Count) 72 return n10s[0][nExp-1]; 73 74 return pow(10.0, static_cast<double>(nExp)); 75 } 76 return 1.0; 77 } 78 79 namespace { 80 81 double const nCorrVal[] = { 82 0, 9e-1, 9e-2, 9e-3, 9e-4, 9e-5, 9e-6, 9e-7, 9e-8, 83 9e-9, 9e-10, 9e-11, 9e-12, 9e-13, 9e-14, 9e-15 84 }; 85 86 struct StringTraits 87 { 88 typedef sal_Char Char; 89 90 typedef rtl_String String; 91 92 static void createString(rtl_String ** pString, 93 char const * pChars, sal_Int32 nLen) 94 { 95 rtl_string_newFromStr_WithLength(pString, pChars, nLen); 96 } 97 98 static void createBuffer(rtl_String ** pBuffer, 99 const sal_Int32 * pCapacity) 100 { 101 rtl_string_new_WithLength(pBuffer, *pCapacity); 102 } 103 104 static void appendChars(rtl_String ** pBuffer, sal_Int32 * pCapacity, 105 sal_Int32 * pOffset, char const * pChars, 106 sal_Int32 nLen) 107 { 108 assert(pChars); 109 rtl_stringbuffer_insert(pBuffer, pCapacity, *pOffset, pChars, nLen); 110 *pOffset += nLen; 111 } 112 113 static void appendAscii(rtl_String ** pBuffer, sal_Int32 * pCapacity, 114 sal_Int32 * pOffset, char const * pStr, 115 sal_Int32 nLen) 116 { 117 assert(pStr); 118 rtl_stringbuffer_insert(pBuffer, pCapacity, *pOffset, pStr, nLen); 119 *pOffset += nLen; 120 } 121 }; 122 123 struct UStringTraits 124 { 125 typedef sal_Unicode Char; 126 127 typedef rtl_uString String; 128 129 static void createString(rtl_uString ** pString, 130 sal_Unicode const * pChars, sal_Int32 nLen) 131 { 132 rtl_uString_newFromStr_WithLength(pString, pChars, nLen); 133 } 134 135 static void createBuffer(rtl_uString ** pBuffer, 136 const sal_Int32 * pCapacity) 137 { 138 rtl_uString_new_WithLength(pBuffer, *pCapacity); 139 } 140 141 static void appendChars(rtl_uString ** pBuffer, 142 sal_Int32 * pCapacity, sal_Int32 * pOffset, 143 sal_Unicode const * pChars, sal_Int32 nLen) 144 { 145 assert(pChars); 146 rtl_uStringbuffer_insert(pBuffer, pCapacity, *pOffset, pChars, nLen); 147 *pOffset += nLen; 148 } 149 150 static void appendAscii(rtl_uString ** pBuffer, 151 sal_Int32 * pCapacity, sal_Int32 * pOffset, 152 char const * pStr, sal_Int32 nLen) 153 { 154 rtl_uStringbuffer_insert_ascii(pBuffer, pCapacity, *pOffset, pStr, 155 nLen); 156 *pOffset += nLen; 157 } 158 }; 159 160 /** If value (passed as absolute value) is an integer representable as double, 161 which we handle explicitly at some places. 162 */ 163 bool isRepresentableInteger(double fAbsValue) 164 { 165 assert(fAbsValue >= 0.0); 166 const sal_Int64 kMaxInt = (static_cast< sal_Int64 >(1) << 53) - 1; 167 if (fAbsValue <= static_cast< double >(kMaxInt)) 168 { 169 sal_Int64 nInt = static_cast< sal_Int64 >(fAbsValue); 170 // Check the integer range again because double comparison may yield 171 // true within the precision range. 172 // XXX loplugin:fpcomparison complains about floating-point comparison 173 // for static_cast<double>(nInt) == fAbsValue, though we actually want 174 // this here. 175 double fInt; 176 return (nInt <= kMaxInt && 177 (!((fInt = static_cast< double >(nInt)) < fAbsValue) && !(fInt > fAbsValue))); 178 } 179 return false; 180 } 181 182 // Returns 1-based index of least significant bit in a number, or zero if number is zero 183 int findFirstSetBit(unsigned n) 184 { 185 #if HAVE_GCC_BUILTIN_FFS 186 return __builtin_ffs(n); 187 #elif defined _WIN32 188 unsigned long pos; 189 unsigned char bNonZero = _BitScanForward(&pos, n); 190 return (bNonZero == 0) ? 0 : pos + 1; 191 #else 192 return ffs(n); 193 #endif 194 } 195 196 /** Returns number of binary bits for fractional part of the number 197 Expects a proper non-negative double value, not +-INF, not NAN 198 */ 199 int getBitsInFracPart(double fAbsValue) 200 { 201 assert(rtl::math::isFinite(fAbsValue) && fAbsValue >= 0.0); 202 if (fAbsValue == 0.0) 203 return 0; 204 auto pValParts = reinterpret_cast< const sal_math_Double * >(&fAbsValue); 205 int nExponent = pValParts->inf_parts.exponent - 1023; 206 if (nExponent >= 52) 207 return 0; // All bits in fraction are in integer part of the number 208 int nLeastSignificant = findFirstSetBit(pValParts->inf_parts.fraction_lo); 209 if (nLeastSignificant == 0) 210 { 211 nLeastSignificant = findFirstSetBit(pValParts->inf_parts.fraction_hi); 212 if (nLeastSignificant == 0) 213 nLeastSignificant = 53; // the implied leading 1 is the least significant 214 else 215 nLeastSignificant += 32; 216 } 217 int nFracSignificant = 53 - nLeastSignificant; 218 int nBitsInFracPart = nFracSignificant - nExponent; 219 220 return std::max(nBitsInFracPart, 0); 221 } 222 223 template< typename T > 224 void doubleToString(typename T::String ** pResult, 225 sal_Int32 * pResultCapacity, sal_Int32 nResultOffset, 226 double fValue, rtl_math_StringFormat eFormat, 227 sal_Int32 nDecPlaces, typename T::Char cDecSeparator, 228 sal_Int32 const * pGroups, 229 typename T::Char cGroupSeparator, 230 bool bEraseTrailingDecZeros) 231 { 232 static double const nRoundVal[] = { 233 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6, 234 0.5e-7, 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14 235 }; 236 237 // sign adjustment, instead of testing for fValue<0.0 this will also fetch 238 // -0.0 239 bool bSign = rtl::math::isSignBitSet(fValue); 240 241 if (bSign) 242 fValue = -fValue; 243 244 if (rtl::math::isNan(fValue)) 245 { 246 // #i112652# XMLSchema-2 247 sal_Int32 nCapacity = RTL_CONSTASCII_LENGTH("NaN"); 248 if (!pResultCapacity) 249 { 250 pResultCapacity = &nCapacity; 251 T::createBuffer(pResult, pResultCapacity); 252 nResultOffset = 0; 253 } 254 255 T::appendAscii(pResult, pResultCapacity, &nResultOffset, 256 RTL_CONSTASCII_STRINGPARAM("NaN")); 257 258 return; 259 } 260 261 bool bHuge = fValue == HUGE_VAL; // g++ 3.0.1 requires it this way... 262 if (bHuge || rtl::math::isInf(fValue)) 263 { 264 // #i112652# XMLSchema-2 265 sal_Int32 nCapacity = RTL_CONSTASCII_LENGTH("-INF"); 266 if (!pResultCapacity) 267 { 268 pResultCapacity = &nCapacity; 269 T::createBuffer(pResult, pResultCapacity); 270 nResultOffset = 0; 271 } 272 273 if ( bSign ) 274 T::appendAscii(pResult, pResultCapacity, &nResultOffset, 275 RTL_CONSTASCII_STRINGPARAM("-")); 276 277 T::appendAscii(pResult, pResultCapacity, &nResultOffset, 278 RTL_CONSTASCII_STRINGPARAM("INF")); 279 280 return; 281 } 282 283 // Use integer representation for integer values that fit into the 284 // mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy. 285 const sal_Int64 kMaxInt = (static_cast< sal_Int64 >(1) << 53) - 1; 286 if ((eFormat == rtl_math_StringFormat_Automatic || 287 eFormat == rtl_math_StringFormat_F) && fValue <= static_cast< double >(kMaxInt)) 288 { 289 sal_Int64 nInt = static_cast< sal_Int64 >(fValue); 290 // Check the integer range again because double comparison may yield 291 // true within the precision range. 292 if (nInt <= kMaxInt && static_cast< double >(nInt) == fValue) 293 { 294 if (nDecPlaces == rtl_math_DecimalPlaces_Max) 295 nDecPlaces = 0; 296 else 297 nDecPlaces = ::std::max< sal_Int32 >(::std::min<sal_Int32>(nDecPlaces, 15), -15); 298 299 if (bEraseTrailingDecZeros && nDecPlaces > 0) 300 nDecPlaces = 0; 301 302 // Round before decimal position. 303 if (nDecPlaces < 0) 304 { 305 sal_Int64 nRounding = static_cast< sal_Int64 >(getN10Exp(-nDecPlaces - 1)); 306 sal_Int64 nTemp = nInt / nRounding; 307 int nDigit = nTemp % 10; 308 nTemp /= 10; 309 310 if (nDigit >= 5) 311 ++nTemp; 312 313 nTemp *= 10; 314 nTemp *= nRounding; 315 nInt = nTemp; 316 nDecPlaces = 0; 317 } 318 319 // Max 1 sign, 16 integer digits, 15 group separators, 1 decimal 320 // separator, 15 decimals digits. 321 typename T::Char aBuf[64]; 322 typename T::Char * pBuf = aBuf; 323 typename T::Char * p = pBuf; 324 325 // Backward fill. 326 size_t nGrouping = 0; 327 sal_Int32 nGroupDigits = 0; 328 do 329 { 330 typename T::Char nDigit = nInt % 10; 331 nInt /= 10; 332 *p++ = nDigit + '0'; 333 if (pGroups && pGroups[nGrouping] == ++nGroupDigits && nInt > 0 && cGroupSeparator) 334 { 335 *p++ = cGroupSeparator; 336 if (pGroups[nGrouping+1]) 337 ++nGrouping; 338 nGroupDigits = 0; 339 } 340 } 341 while (nInt > 0); 342 if (bSign) 343 *p++ = '-'; 344 345 // Reverse buffer content. 346 sal_Int32 n = (p - pBuf) / 2; 347 for (sal_Int32 i=0; i < n; ++i) 348 { 349 ::std::swap( pBuf[i], p[-i-1]); 350 } 351 352 // Append decimals. 353 if (nDecPlaces > 0) 354 { 355 *p++ = cDecSeparator; 356 while (nDecPlaces--) 357 *p++ = '0'; 358 } 359 360 if (!pResultCapacity) 361 T::createString(pResult, pBuf, p - pBuf); 362 else 363 T::appendChars(pResult, pResultCapacity, &nResultOffset, pBuf, p - pBuf); 364 365 return; 366 } 367 } 368 369 // find the exponent 370 int nExp = 0; 371 if ( fValue > 0.0 ) 372 { 373 // Cap nExp at a small value beyond which "fValue /= N10Exp" would lose precision (or N10Exp 374 // might even be zero); that will produce output with the decimal point in a non-normalized 375 // position, but the current quality of output for such small values is probably abysmal, 376 // anyway: 377 nExp = std::max( 378 static_cast< int >(floor(log10(fValue))), std::numeric_limits<double>::min_exponent10); 379 double const N10Exp = getN10Exp(nExp); 380 assert(N10Exp != 0); 381 fValue /= N10Exp; 382 } 383 384 switch (eFormat) 385 { 386 case rtl_math_StringFormat_Automatic: 387 { // E or F depending on exponent magnitude 388 int nPrec; 389 if (nExp <= -15 || nExp >= 15) // was <-16, >16 in ancient versions, which leads to inaccuracies 390 { 391 nPrec = 14; 392 eFormat = rtl_math_StringFormat_E; 393 } 394 else 395 { 396 if (nExp < 14) 397 { 398 nPrec = 15 - nExp - 1; 399 eFormat = rtl_math_StringFormat_F; 400 } 401 else 402 { 403 nPrec = 15; 404 eFormat = rtl_math_StringFormat_F; 405 } 406 } 407 408 if (nDecPlaces == rtl_math_DecimalPlaces_Max) 409 nDecPlaces = nPrec; 410 } 411 break; 412 413 case rtl_math_StringFormat_G : 414 case rtl_math_StringFormat_G1 : 415 case rtl_math_StringFormat_G2 : 416 { // G-Point, similar to sprintf %G 417 if (nDecPlaces == rtl_math_DecimalPlaces_DefaultSignificance) 418 nDecPlaces = 6; 419 420 if (nExp < -4 || nExp >= nDecPlaces) 421 { 422 nDecPlaces = std::max< sal_Int32 >(1, nDecPlaces - 1); 423 424 if (eFormat == rtl_math_StringFormat_G) 425 eFormat = rtl_math_StringFormat_E; 426 else if (eFormat == rtl_math_StringFormat_G2) 427 eFormat = rtl_math_StringFormat_E2; 428 else if (eFormat == rtl_math_StringFormat_G1) 429 eFormat = rtl_math_StringFormat_E1; 430 } 431 else 432 { 433 nDecPlaces = std::max< sal_Int32 >(0, nDecPlaces - nExp - 1); 434 eFormat = rtl_math_StringFormat_F; 435 } 436 } 437 break; 438 default: 439 break; 440 } 441 442 sal_Int32 nDigits = nDecPlaces + 1; 443 444 if (eFormat == rtl_math_StringFormat_F) 445 nDigits += nExp; 446 447 // Round the number 448 if(nDigits >= 0) 449 { 450 if ((fValue += nRoundVal[std::min<sal_Int32>(nDigits, 15)] ) >= 10) 451 { 452 fValue = 1.0; 453 nExp++; 454 455 if (eFormat == rtl_math_StringFormat_F) 456 nDigits++; 457 } 458 } 459 460 static sal_Int32 const nBufMax = 256; 461 typename T::Char aBuf[nBufMax]; 462 typename T::Char * pBuf; 463 sal_Int32 nBuf = static_cast< sal_Int32 > 464 (nDigits <= 0 ? std::max< sal_Int32 >(nDecPlaces, abs(nExp)) 465 : nDigits + nDecPlaces ) + 10 + (pGroups ? abs(nDigits) * 2 : 0); 466 467 if (nBuf > nBufMax) 468 { 469 pBuf = static_cast< typename T::Char * >( 470 malloc(nBuf * sizeof (typename T::Char))); 471 OSL_ENSURE(pBuf, "Out of memory"); 472 } 473 else 474 { 475 pBuf = aBuf; 476 } 477 478 typename T::Char * p = pBuf; 479 if ( bSign ) 480 *p++ = static_cast< typename T::Char >('-'); 481 482 bool bHasDec = false; 483 484 int nDecPos; 485 // Check for F format and number < 1 486 if(eFormat == rtl_math_StringFormat_F) 487 { 488 if(nExp < 0) 489 { 490 *p++ = static_cast< typename T::Char >('0'); 491 if (nDecPlaces > 0) 492 { 493 *p++ = cDecSeparator; 494 bHasDec = true; 495 } 496 497 sal_Int32 i = (nDigits <= 0 ? nDecPlaces : -nExp - 1); 498 499 while((i--) > 0) 500 { 501 *p++ = static_cast< typename T::Char >('0'); 502 } 503 504 nDecPos = 0; 505 } 506 else 507 { 508 nDecPos = nExp + 1; 509 } 510 } 511 else 512 { 513 nDecPos = 1; 514 } 515 516 int nGrouping = 0, nGroupSelector = 0, nGroupExceed = 0; 517 if (nDecPos > 1 && pGroups && pGroups[0] && cGroupSeparator) 518 { 519 while (nGrouping + pGroups[nGroupSelector] < nDecPos) 520 { 521 nGrouping += pGroups[nGroupSelector]; 522 if (pGroups[nGroupSelector+1]) 523 { 524 if (nGrouping + pGroups[nGroupSelector+1] >= nDecPos) 525 break; // while 526 527 ++nGroupSelector; 528 } 529 else if (!nGroupExceed) 530 { 531 nGroupExceed = nGrouping; 532 } 533 } 534 } 535 536 // print the number 537 if (nDigits > 0) 538 { 539 for (int i = 0; ; i++) 540 { 541 if (i < 15) // was 16 in ancient versions, which leads to inaccuracies 542 { 543 int nDigit; 544 if (nDigits-1 == 0 && i > 0 && i < 14) 545 nDigit = static_cast< int >(floor( fValue + nCorrVal[15-i])); 546 else 547 nDigit = static_cast< int >(fValue + 1E-15); 548 549 if (nDigit >= 10) 550 { // after-treatment of up-rounding to the next decade 551 sal_Int32 sLen = static_cast< long >(p-pBuf)-1; 552 if (sLen == -1 || (sLen == 0 && bSign)) 553 { 554 // Assert that no one changed the logic we rely on. 555 assert(!bSign || *pBuf == static_cast< typename T::Char >('-')); 556 p = pBuf; 557 if (bSign) 558 ++p; 559 if (eFormat == rtl_math_StringFormat_F) 560 { 561 *p++ = static_cast< typename T::Char >('1'); 562 *p++ = static_cast< typename T::Char >('0'); 563 } 564 else 565 { 566 *p++ = static_cast< typename T::Char >('1'); 567 *p++ = cDecSeparator; 568 *p++ = static_cast< typename T::Char >('0'); 569 nExp++; 570 bHasDec = true; 571 } 572 } 573 else 574 { 575 for (sal_Int32 j = sLen; j >= 0; j--) 576 { 577 typename T::Char cS = pBuf[j]; 578 if (j == 0 && bSign) 579 { 580 // Do not touch leading minus sign put earlier. 581 assert(cS == static_cast< typename T::Char >('-')); 582 break; // for, this is the last character backwards. 583 } 584 if (cS != cDecSeparator) 585 { 586 if (cS != static_cast< typename T::Char >('9')) 587 { 588 pBuf[j] = ++cS; 589 j = -1; // break loop 590 } 591 else 592 { 593 pBuf[j] = static_cast< typename T::Char >('0'); 594 if (j == 0 || (j == 1 && bSign)) 595 { 596 if (eFormat == rtl_math_StringFormat_F) 597 { // insert '1' 598 typename T::Char * px = p++; 599 while (pBuf < px) 600 { 601 *px = *(px-1); 602 px--; 603 } 604 605 pBuf[0] = static_cast< typename T::Char >('1'); 606 } 607 else 608 { 609 pBuf[j] = static_cast< typename T::Char >('1'); 610 nExp++; 611 } 612 } 613 } 614 } 615 } 616 617 *p++ = static_cast< typename T::Char >('0'); 618 } 619 fValue = 0.0; 620 } 621 else 622 { 623 *p++ = static_cast< typename T::Char >( 624 nDigit + static_cast< typename T::Char >('0') ); 625 fValue = (fValue - nDigit) * 10.0; 626 } 627 } 628 else 629 { 630 *p++ = static_cast< typename T::Char >('0'); 631 } 632 633 if (!--nDigits) 634 break; // for 635 636 if (nDecPos) 637 { 638 if(!--nDecPos) 639 { 640 *p++ = cDecSeparator; 641 bHasDec = true; 642 } 643 else if (nDecPos == nGrouping) 644 { 645 *p++ = cGroupSeparator; 646 nGrouping -= pGroups[nGroupSelector]; 647 648 if (nGroupSelector && nGrouping < nGroupExceed) 649 --nGroupSelector; 650 } 651 } 652 } 653 } 654 655 if (!bHasDec && eFormat == rtl_math_StringFormat_F) 656 { // nDecPlaces < 0 did round the value 657 while (--nDecPos > 0) 658 { // fill before decimal point 659 if (nDecPos == nGrouping) 660 { 661 *p++ = cGroupSeparator; 662 nGrouping -= pGroups[nGroupSelector]; 663 664 if (nGroupSelector && nGrouping < nGroupExceed) 665 --nGroupSelector; 666 } 667 668 *p++ = static_cast< typename T::Char >('0'); 669 } 670 } 671 672 if (bEraseTrailingDecZeros && bHasDec && p > pBuf) 673 { 674 while (*(p-1) == static_cast< typename T::Char >('0')) 675 { 676 p--; 677 } 678 679 if (*(p-1) == cDecSeparator) 680 p--; 681 } 682 683 // Print the exponent ('E', followed by '+' or '-', followed by exactly 684 // three digits for rtl_math_StringFormat_E). The code in 685 // rtl_[u]str_valueOf{Float|Double} relies on this format. 686 if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 || eFormat == rtl_math_StringFormat_E1) 687 { 688 if (p == pBuf) 689 *p++ = static_cast< typename T::Char >('1'); 690 // maybe no nDigits if nDecPlaces < 0 691 692 *p++ = static_cast< typename T::Char >('E'); 693 if(nExp < 0) 694 { 695 nExp = -nExp; 696 *p++ = static_cast< typename T::Char >('-'); 697 } 698 else 699 { 700 *p++ = static_cast< typename T::Char >('+'); 701 } 702 703 if (eFormat == rtl_math_StringFormat_E || nExp >= 100) 704 *p++ = static_cast< typename T::Char >( 705 nExp / 100 + static_cast< typename T::Char >('0') ); 706 707 nExp %= 100; 708 709 if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 || nExp >= 10) 710 *p++ = static_cast< typename T::Char >( 711 nExp / 10 + static_cast< typename T::Char >('0') ); 712 713 *p++ = static_cast< typename T::Char >( 714 nExp % 10 + static_cast< typename T::Char >('0') ); 715 } 716 717 if (!pResultCapacity) 718 T::createString(pResult, pBuf, p - pBuf); 719 else 720 T::appendChars(pResult, pResultCapacity, &nResultOffset, pBuf, p - pBuf); 721 722 if (pBuf != &aBuf[0]) 723 free(pBuf); 724 } 725 726 } 727 728 void SAL_CALL rtl_math_doubleToString(rtl_String ** pResult, 729 sal_Int32 * pResultCapacity, 730 sal_Int32 nResultOffset, double fValue, 731 rtl_math_StringFormat eFormat, 732 sal_Int32 nDecPlaces, 733 char cDecSeparator, 734 sal_Int32 const * pGroups, 735 char cGroupSeparator, 736 sal_Bool bEraseTrailingDecZeros) 737 SAL_THROW_EXTERN_C() 738 { 739 doubleToString< StringTraits >( 740 pResult, pResultCapacity, nResultOffset, fValue, eFormat, nDecPlaces, 741 cDecSeparator, pGroups, cGroupSeparator, bEraseTrailingDecZeros); 742 } 743 744 void SAL_CALL rtl_math_doubleToUString(rtl_uString ** pResult, 745 sal_Int32 * pResultCapacity, 746 sal_Int32 nResultOffset, double fValue, 747 rtl_math_StringFormat eFormat, 748 sal_Int32 nDecPlaces, 749 sal_Unicode cDecSeparator, 750 sal_Int32 const * pGroups, 751 sal_Unicode cGroupSeparator, 752 sal_Bool bEraseTrailingDecZeros) 753 SAL_THROW_EXTERN_C() 754 { 755 doubleToString< UStringTraits >( 756 pResult, pResultCapacity, nResultOffset, fValue, eFormat, nDecPlaces, 757 cDecSeparator, pGroups, cGroupSeparator, bEraseTrailingDecZeros); 758 } 759 760 namespace { 761 762 template< typename CharT > 763 double stringToDouble(CharT const * pBegin, CharT const * pEnd, 764 CharT cDecSeparator, CharT cGroupSeparator, 765 rtl_math_ConversionStatus * pStatus, 766 CharT const ** pParsedEnd) 767 { 768 double fVal = 0.0; 769 rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; 770 771 CharT const * p0 = pBegin; 772 while (p0 != pEnd && (*p0 == CharT(' ') || *p0 == CharT('\t'))) 773 { 774 ++p0; 775 } 776 777 bool bSign; 778 if (p0 != pEnd && *p0 == CharT('-')) 779 { 780 bSign = true; 781 ++p0; 782 } 783 else 784 { 785 bSign = false; 786 if (p0 != pEnd && *p0 == CharT('+')) 787 ++p0; 788 } 789 790 CharT const * p = p0; 791 bool bDone = false; 792 793 // #i112652# XMLSchema-2 794 if ((pEnd - p) >= 3) 795 { 796 if ((CharT('N') == p[0]) && (CharT('a') == p[1]) 797 && (CharT('N') == p[2])) 798 { 799 p += 3; 800 rtl::math::setNan( &fVal ); 801 bDone = true; 802 } 803 else if ((CharT('I') == p[0]) && (CharT('N') == p[1]) 804 && (CharT('F') == p[2])) 805 { 806 p += 3; 807 fVal = HUGE_VAL; 808 eStatus = rtl_math_ConversionStatus_OutOfRange; 809 bDone = true; 810 } 811 } 812 813 if (!bDone) // do not recognize e.g. NaN1.23 814 { 815 std::unique_ptr<char[]> bufInHeap; 816 std::unique_ptr<const CharT * []> bufInHeapMap; 817 constexpr int bufOnStackSize = 256; 818 char bufOnStack[bufOnStackSize]; 819 const CharT* bufOnStackMap[bufOnStackSize]; 820 char* buf = bufOnStack; 821 const CharT** bufmap = bufOnStackMap; 822 int bufpos = 0; 823 const size_t bufsize = pEnd - p + (bSign ? 2 : 1); 824 if (bufsize > bufOnStackSize) 825 { 826 bufInHeap = std::make_unique<char[]>(bufsize); 827 bufInHeapMap = std::make_unique<const CharT*[]>(bufsize); 828 buf = bufInHeap.get(); 829 bufmap = bufInHeapMap.get(); 830 } 831 832 if (bSign) 833 { 834 buf[0] = '-'; 835 bufmap[0] = p; // yes, this may be the same pointer as for the next mapping 836 bufpos = 1; 837 } 838 // Put first zero to buffer for strings like "-0" 839 if (p != pEnd && *p == CharT('0')) 840 { 841 buf[bufpos] = '0'; 842 bufmap[bufpos] = p; 843 ++bufpos; 844 ++p; 845 } 846 // Leading zeros and group separators between digits may be safely 847 // ignored. p0 < p implies that there was a leading 0 already, 848 // consecutive group separators may not happen as *(p+1) is checked for 849 // digit. 850 while (p != pEnd && (*p == CharT('0') || (*p == cGroupSeparator 851 && p0 < p && p+1 < pEnd && rtl::isAsciiDigit(*(p+1))))) 852 { 853 ++p; 854 } 855 856 // integer part of mantissa 857 for (; p != pEnd; ++p) 858 { 859 CharT c = *p; 860 if (rtl::isAsciiDigit(c)) 861 { 862 buf[bufpos] = static_cast<char>(c); 863 bufmap[bufpos] = p; 864 ++bufpos; 865 } 866 else if (c != cGroupSeparator) 867 { 868 break; 869 } 870 else if (p == p0 || (p+1 == pEnd) || !rtl::isAsciiDigit(*(p+1))) 871 { 872 // A leading or trailing (not followed by a digit) group 873 // separator character is not a group separator. 874 break; 875 } 876 } 877 878 // fraction part of mantissa 879 if (p != pEnd && *p == cDecSeparator) 880 { 881 buf[bufpos] = '.'; 882 bufmap[bufpos] = p; 883 ++bufpos; 884 ++p; 885 886 for (; p != pEnd; ++p) 887 { 888 CharT c = *p; 889 if (!rtl::isAsciiDigit(c)) 890 { 891 break; 892 } 893 buf[bufpos] = static_cast<char>(c); 894 bufmap[bufpos] = p; 895 ++bufpos; 896 } 897 } 898 899 // Exponent 900 if (p != p0 && p != pEnd && (*p == CharT('E') || *p == CharT('e'))) 901 { 902 buf[bufpos] = 'E'; 903 bufmap[bufpos] = p; 904 ++bufpos; 905 ++p; 906 if (p != pEnd && *p == CharT('-')) 907 { 908 buf[bufpos] = '-'; 909 bufmap[bufpos] = p; 910 ++bufpos; 911 ++p; 912 } 913 else if (p != pEnd && *p == CharT('+')) 914 ++p; 915 916 for (; p != pEnd; ++p) 917 { 918 CharT c = *p; 919 if (!rtl::isAsciiDigit(c)) 920 break; 921 922 buf[bufpos] = static_cast<char>(c); 923 bufmap[bufpos] = p; 924 ++bufpos; 925 } 926 } 927 else if (p - p0 == 2 && p != pEnd && p[0] == CharT('#') 928 && p[-1] == cDecSeparator && p[-2] == CharT('1')) 929 { 930 if (pEnd - p >= 4 && p[1] == CharT('I') && p[2] == CharT('N') 931 && p[3] == CharT('F')) 932 { 933 // "1.#INF", "+1.#INF", "-1.#INF" 934 p += 4; 935 fVal = HUGE_VAL; 936 eStatus = rtl_math_ConversionStatus_OutOfRange; 937 // Eat any further digits: 938 while (p != pEnd && rtl::isAsciiDigit(*p)) 939 ++p; 940 bDone = true; 941 } 942 else if (pEnd - p >= 4 && p[1] == CharT('N') && p[2] == CharT('A') 943 && p[3] == CharT('N')) 944 { 945 // "1.#NAN", "+1.#NAN", "-1.#NAN" 946 p += 4; 947 rtl::math::setNan( &fVal ); 948 if (bSign) 949 { 950 union { 951 double sd; 952 sal_math_Double md; 953 } m; 954 955 m.sd = fVal; 956 m.md.w32_parts.msw |= 0x80000000; // create negative NaN 957 fVal = m.sd; 958 bSign = false; // don't negate again 959 } 960 961 // Eat any further digits: 962 while (p != pEnd && rtl::isAsciiDigit(*p)) 963 { 964 ++p; 965 } 966 bDone = true; 967 } 968 } 969 970 if (!bDone) 971 { 972 buf[bufpos] = '\0'; 973 bufmap[bufpos] = p; 974 char* pCharParseEnd; 975 errno = 0; 976 fVal = strtod_nolocale(buf, &pCharParseEnd); 977 if (errno == ERANGE) 978 eStatus = rtl_math_ConversionStatus_OutOfRange; 979 p = bufmap[pCharParseEnd - buf]; 980 bSign = false; 981 } 982 } 983 984 // overflow also if more than DBL_MAX_10_EXP digits without decimal 985 // separator, or 0. and more than DBL_MIN_10_EXP digits, ... 986 bool bHuge = fVal == HUGE_VAL; // g++ 3.0.1 requires it this way... 987 if (bHuge) 988 eStatus = rtl_math_ConversionStatus_OutOfRange; 989 990 if (bSign) 991 fVal = -fVal; 992 993 if (pStatus) 994 *pStatus = eStatus; 995 996 if (pParsedEnd) 997 *pParsedEnd = p == p0 ? pBegin : p; 998 999 return fVal; 1000 } 1001 1002 } 1003 1004 double SAL_CALL rtl_math_stringToDouble(char const * pBegin, 1005 char const * pEnd, 1006 char cDecSeparator, 1007 char cGroupSeparator, 1008 rtl_math_ConversionStatus * pStatus, 1009 char const ** pParsedEnd) 1010 SAL_THROW_EXTERN_C() 1011 { 1012 return stringToDouble( 1013 reinterpret_cast<unsigned char const *>(pBegin), 1014 reinterpret_cast<unsigned char const *>(pEnd), 1015 static_cast<unsigned char>(cDecSeparator), 1016 static_cast<unsigned char>(cGroupSeparator), pStatus, 1017 reinterpret_cast<unsigned char const **>(pParsedEnd)); 1018 } 1019 1020 double SAL_CALL rtl_math_uStringToDouble(sal_Unicode const * pBegin, 1021 sal_Unicode const * pEnd, 1022 sal_Unicode cDecSeparator, 1023 sal_Unicode cGroupSeparator, 1024 rtl_math_ConversionStatus * pStatus, 1025 sal_Unicode const ** pParsedEnd) 1026 SAL_THROW_EXTERN_C() 1027 { 1028 return stringToDouble(pBegin, pEnd, cDecSeparator, cGroupSeparator, pStatus, 1029 pParsedEnd); 1030 } 1031 1032 double SAL_CALL rtl_math_round(double fValue, int nDecPlaces, 1033 enum rtl_math_RoundingMode eMode) 1034 SAL_THROW_EXTERN_C() 1035 { 1036 OSL_ASSERT(nDecPlaces >= -20 && nDecPlaces <= 20); 1037 1038 if (fValue == 0.0) 1039 return fValue; 1040 1041 if ( nDecPlaces == 0 && eMode == rtl_math_RoundingMode_Corrected ) 1042 return std::round( fValue ); 1043 1044 // sign adjustment 1045 bool bSign = rtl::math::isSignBitSet( fValue ); 1046 if (bSign) 1047 fValue = -fValue; 1048 1049 double fFac = 0; 1050 if (nDecPlaces != 0) 1051 { 1052 // max 20 decimals, we don't have unlimited precision 1053 // #38810# and no overflow on fValue*=fFac 1054 if (nDecPlaces < -20 || 20 < nDecPlaces || fValue > (DBL_MAX / 1e20)) 1055 return bSign ? -fValue : fValue; 1056 1057 fFac = getN10Exp(nDecPlaces); 1058 fValue *= fFac; 1059 } 1060 1061 switch ( eMode ) 1062 { 1063 case rtl_math_RoundingMode_Corrected : 1064 { 1065 int nExp; // exponent for correction 1066 if ( fValue > 0.0 ) 1067 nExp = static_cast<int>( floor( log10( fValue ) ) ); 1068 else 1069 nExp = 0; 1070 1071 int nIndex; 1072 1073 if (nExp < 0) 1074 nIndex = 15; 1075 else if (nExp >= 14) 1076 nIndex = 0; 1077 else 1078 nIndex = 15 - nExp; 1079 1080 fValue = floor(fValue + 0.5 + nCorrVal[nIndex]); 1081 } 1082 break; 1083 case rtl_math_RoundingMode_Down: 1084 fValue = rtl::math::approxFloor(fValue); 1085 break; 1086 case rtl_math_RoundingMode_Up: 1087 fValue = rtl::math::approxCeil(fValue); 1088 break; 1089 case rtl_math_RoundingMode_Floor: 1090 fValue = bSign ? rtl::math::approxCeil(fValue) 1091 : rtl::math::approxFloor( fValue ); 1092 break; 1093 case rtl_math_RoundingMode_Ceiling: 1094 fValue = bSign ? rtl::math::approxFloor(fValue) 1095 : rtl::math::approxCeil(fValue); 1096 break; 1097 case rtl_math_RoundingMode_HalfDown : 1098 { 1099 double f = floor(fValue); 1100 fValue = ((fValue - f) <= 0.5) ? f : ceil(fValue); 1101 } 1102 break; 1103 case rtl_math_RoundingMode_HalfUp: 1104 { 1105 double f = floor(fValue); 1106 fValue = ((fValue - f) < 0.5) ? f : ceil(fValue); 1107 } 1108 break; 1109 case rtl_math_RoundingMode_HalfEven: 1110 #if defined FLT_ROUNDS 1111 /* 1112 Use fast version. FLT_ROUNDS may be defined to a function by some compilers! 1113 1114 DBL_EPSILON is the smallest fractional number which can be represented, 1115 its reciprocal is therefore the smallest number that cannot have a 1116 fractional part. Once you add this reciprocal to `x', its fractional part 1117 is stripped off. Simply subtracting the reciprocal back out returns `x' 1118 without its fractional component. 1119 Simple, clever, and elegant - thanks to Ross Cottrell, the original author, 1120 who placed it into public domain. 1121 1122 volatile: prevent compiler from being too smart 1123 */ 1124 if (FLT_ROUNDS == 1) 1125 { 1126 volatile double x = fValue + 1.0 / DBL_EPSILON; 1127 fValue = x - 1.0 / DBL_EPSILON; 1128 } 1129 else 1130 #endif // FLT_ROUNDS 1131 { 1132 double f = floor(fValue); 1133 if ((fValue - f) != 0.5) 1134 { 1135 fValue = floor( fValue + 0.5 ); 1136 } 1137 else 1138 { 1139 double g = f / 2.0; 1140 fValue = (g == floor( g )) ? f : (f + 1.0); 1141 } 1142 } 1143 break; 1144 default: 1145 OSL_ASSERT(false); 1146 break; 1147 } 1148 1149 if (nDecPlaces != 0) 1150 fValue /= fFac; 1151 1152 return bSign ? -fValue : fValue; 1153 } 1154 1155 double SAL_CALL rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C() 1156 { 1157 return fValue * getN10Exp(nExp); 1158 } 1159 1160 double SAL_CALL rtl_math_approxValue( double fValue ) SAL_THROW_EXTERN_C() 1161 { 1162 const double fBigInt = 2199023255552.0; // 2^41 -> only 11 bits left for fractional part, fine as decimal 1163 if (fValue == 0.0 || fValue == HUGE_VAL || !::rtl::math::isFinite( fValue) || fValue > fBigInt) 1164 { 1165 // We don't handle these conditions. Bail out. 1166 return fValue; 1167 } 1168 1169 double fOrigValue = fValue; 1170 1171 bool bSign = ::rtl::math::isSignBitSet(fValue); 1172 if (bSign) 1173 fValue = -fValue; 1174 1175 // If the value is either integer representable as double, 1176 // or only has small number of bits in fraction part, then we need not do any approximation 1177 if (isRepresentableInteger(fValue) || getBitsInFracPart(fValue) <= 11) 1178 return fOrigValue; 1179 1180 int nExp = static_cast< int >(floor(log10(fValue))); 1181 nExp = 14 - nExp; 1182 double fExpValue = getN10Exp(nExp); 1183 1184 fValue *= fExpValue; 1185 // If the original value was near DBL_MIN we got an overflow. Restore and 1186 // bail out. 1187 if (!rtl::math::isFinite(fValue)) 1188 return fOrigValue; 1189 1190 fValue = rtl_math_round(fValue, 0, rtl_math_RoundingMode_Corrected); 1191 fValue /= fExpValue; 1192 1193 // If the original value was near DBL_MAX we got an overflow. Restore and 1194 // bail out. 1195 if (!rtl::math::isFinite(fValue)) 1196 return fOrigValue; 1197 1198 return bSign ? -fValue : fValue; 1199 } 1200 1201 bool SAL_CALL rtl_math_approxEqual(double a, double b) SAL_THROW_EXTERN_C() 1202 { 1203 static const double e48 = 1.0 / (16777216.0 * 16777216.0); 1204 static const double e44 = e48 * 16.0; 1205 1206 if (a == b) 1207 return true; 1208 1209 if (a == 0.0 || b == 0.0) 1210 return false; 1211 1212 const double d = fabs(a - b); 1213 if (!rtl::math::isFinite(d)) 1214 return false; // Nan or Inf involved 1215 1216 if (d > ((a = fabs(a)) * e44) || d > ((b = fabs(b)) * e44)) 1217 return false; 1218 1219 if (isRepresentableInteger(d) && isRepresentableInteger(a) && isRepresentableInteger(b)) 1220 return false; // special case for representable integers. 1221 1222 return (d < a * e48 && d < b * e48); 1223 } 1224 1225 double SAL_CALL rtl_math_expm1(double fValue) SAL_THROW_EXTERN_C() 1226 { 1227 return expm1(fValue); 1228 } 1229 1230 double SAL_CALL rtl_math_log1p(double fValue) SAL_THROW_EXTERN_C() 1231 { 1232 #ifdef __APPLE__ 1233 if (fValue == -0.0) 1234 return fValue; // macOS 10.8 libc returns 0.0 for -0.0 1235 #endif 1236 1237 return log1p(fValue); 1238 } 1239 1240 double SAL_CALL rtl_math_atanh(double fValue) SAL_THROW_EXTERN_C() 1241 #if defined __clang__ 1242 __attribute__((no_sanitize("float-divide-by-zero"))) // atahn(1) -> inf 1243 #endif 1244 { 1245 return 0.5 * rtl_math_log1p(2.0 * fValue / (1.0-fValue)); 1246 } 1247 1248 /** Parent error function (erf) */ 1249 double SAL_CALL rtl_math_erf(double x) SAL_THROW_EXTERN_C() 1250 { 1251 return erf(x); 1252 } 1253 1254 /** Parent complementary error function (erfc) */ 1255 double SAL_CALL rtl_math_erfc(double x) SAL_THROW_EXTERN_C() 1256 { 1257 return erfc(x); 1258 } 1259 1260 /** improved accuracy of asinh for |x| large and for x near zero 1261 @see #i97605# 1262 */ 1263 double SAL_CALL rtl_math_asinh(double fX) SAL_THROW_EXTERN_C() 1264 { 1265 if ( fX == 0.0 ) 1266 return 0.0; 1267 1268 double fSign = 1.0; 1269 if ( fX < 0.0 ) 1270 { 1271 fX = - fX; 1272 fSign = -1.0; 1273 } 1274 1275 if ( fX < 0.125 ) 1276 return fSign * rtl_math_log1p( fX + fX*fX / (1.0 + sqrt( 1.0 + fX*fX))); 1277 1278 if ( fX < 1.25e7 ) 1279 return fSign * log( fX + sqrt( 1.0 + fX*fX)); 1280 1281 return fSign * log( 2.0*fX); 1282 } 1283 1284 /** improved accuracy of acosh for x large and for x near 1 1285 @see #i97605# 1286 */ 1287 double SAL_CALL rtl_math_acosh(double fX) SAL_THROW_EXTERN_C() 1288 { 1289 volatile double fZ = fX - 1.0; 1290 if (fX < 1.0) 1291 { 1292 double fResult; 1293 ::rtl::math::setNan( &fResult ); 1294 return fResult; 1295 } 1296 if ( fX == 1.0 ) 1297 return 0.0; 1298 1299 if ( fX < 1.1 ) 1300 return rtl_math_log1p( fZ + sqrt( fZ*fZ + 2.0*fZ)); 1301 1302 if ( fX < 1.25e7 ) 1303 return log( fX + sqrt( fX*fX - 1.0)); 1304 1305 return log( 2.0*fX); 1306 } 1307 1308 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1309
