1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
43 #if !HAVE_GCC_BUILTIN_FFS && !defined _WIN32
47 static int const n10Count
= 16;
48 static double const n10s
[2][n10Count
] = {
49 { 1e1
, 1e2
, 1e3
, 1e4
, 1e5
, 1e6
, 1e7
, 1e8
,
50 1e9
, 1e10
, 1e11
, 1e12
, 1e13
, 1e14
, 1e15
, 1e16
},
51 { 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8,
52 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16 }
55 // return pow(10.0,nExp) optimized for exponents in the interval [-16,16]
56 static double getN10Exp(int nExp
)
60 // && -nExp > 0 necessary for std::numeric_limits<int>::min()
61 // because -nExp = nExp
62 if (-nExp
<= n10Count
&& -nExp
> 0)
63 return n10s
[1][-nExp
-1];
64 return pow(10.0, static_cast<double>(nExp
));
69 return n10s
[0][nExp
-1];
71 return pow(10.0, static_cast<double>(nExp
));
78 double const nCorrVal
[] = {
79 0, 9e-1, 9e-2, 9e-3, 9e-4, 9e-5, 9e-6, 9e-7, 9e-8,
80 9e-9, 9e-10, 9e-11, 9e-12, 9e-13, 9e-14, 9e-15
85 typedef sal_Char Char
;
87 typedef rtl_String String
;
89 static void createString(rtl_String
** pString
,
90 sal_Char
const * pChars
, sal_Int32 nLen
)
92 rtl_string_newFromStr_WithLength(pString
, pChars
, nLen
);
95 static void createBuffer(rtl_String
** pBuffer
,
96 const sal_Int32
* pCapacity
)
98 rtl_string_new_WithLength(pBuffer
, *pCapacity
);
101 static void appendChars(rtl_String
** pBuffer
, sal_Int32
* pCapacity
,
102 sal_Int32
* pOffset
, sal_Char
const * pChars
,
106 rtl_stringbuffer_insert(pBuffer
, pCapacity
, *pOffset
, pChars
, nLen
);
110 static void appendAscii(rtl_String
** pBuffer
, sal_Int32
* pCapacity
,
111 sal_Int32
* pOffset
, sal_Char
const * pStr
,
115 rtl_stringbuffer_insert(pBuffer
, pCapacity
, *pOffset
, pStr
, nLen
);
122 typedef sal_Unicode Char
;
124 typedef rtl_uString String
;
126 static void createString(rtl_uString
** pString
,
127 sal_Unicode
const * pChars
, sal_Int32 nLen
)
129 rtl_uString_newFromStr_WithLength(pString
, pChars
, nLen
);
132 static void createBuffer(rtl_uString
** pBuffer
,
133 const sal_Int32
* pCapacity
)
135 rtl_uString_new_WithLength(pBuffer
, *pCapacity
);
138 static void appendChars(rtl_uString
** pBuffer
,
139 sal_Int32
* pCapacity
, sal_Int32
* pOffset
,
140 sal_Unicode
const * pChars
, sal_Int32 nLen
)
143 rtl_uStringbuffer_insert(pBuffer
, pCapacity
, *pOffset
, pChars
, nLen
);
147 static void appendAscii(rtl_uString
** pBuffer
,
148 sal_Int32
* pCapacity
, sal_Int32
* pOffset
,
149 sal_Char
const * pStr
, sal_Int32 nLen
)
151 rtl_uStringbuffer_insert_ascii(pBuffer
, pCapacity
, *pOffset
, pStr
,
157 /** If value (passed as absolute value) is an integer representable as double,
158 which we handle explicitly at some places.
160 bool isRepresentableInteger(double fAbsValue
)
162 assert(fAbsValue
>= 0.0);
163 const sal_Int64 kMaxInt
= (static_cast< sal_Int64
>(1) << 53) - 1;
164 if (fAbsValue
<= static_cast< double >(kMaxInt
))
166 sal_Int64 nInt
= static_cast< sal_Int64
>(fAbsValue
);
167 // Check the integer range again because double comparison may yield
168 // true within the precision range.
169 // XXX loplugin:fpcomparison complains about floating-point comparison
170 // for static_cast<double>(nInt) == fAbsValue, though we actually want
173 return (nInt
<= kMaxInt
&&
174 (!((fInt
= static_cast< double >(nInt
)) < fAbsValue
) && !(fInt
> fAbsValue
)));
179 // Returns 1-based index of least significant bit in a number, or zero if number is zero
180 int findFirstSetBit(unsigned n
)
182 #if HAVE_GCC_BUILTIN_FFS
183 return __builtin_ffs(n
);
186 unsigned char bNonZero
= _BitScanForward(&pos
, n
);
187 return (bNonZero
== 0) ? 0 : pos
+ 1;
193 /** Returns number of binary bits for fractional part of the number
194 Expects a proper non-negative double value, not +-INF, not NAN
196 int getBitsInFracPart(double fAbsValue
)
198 assert(rtl::math::isFinite(fAbsValue
) && fAbsValue
>= 0.0);
199 if (fAbsValue
== 0.0)
201 auto pValParts
= reinterpret_cast< const sal_math_Double
* >(&fAbsValue
);
202 int nExponent
= pValParts
->inf_parts
.exponent
- 1023;
204 return 0; // All bits in fraction are in integer part of the number
205 int nLeastSignificant
= findFirstSetBit(pValParts
->inf_parts
.fraction_lo
);
206 if (nLeastSignificant
== 0)
208 nLeastSignificant
= findFirstSetBit(pValParts
->inf_parts
.fraction_hi
);
209 if (nLeastSignificant
== 0)
210 nLeastSignificant
= 53; // the implied leading 1 is the least significant
212 nLeastSignificant
+= 32;
214 int nFracSignificant
= 53 - nLeastSignificant
;
215 int nBitsInFracPart
= nFracSignificant
- nExponent
;
217 return std::max(nBitsInFracPart
, 0);
220 template< typename T
>
221 void doubleToString(typename
T::String
** pResult
,
222 sal_Int32
* pResultCapacity
, sal_Int32 nResultOffset
,
223 double fValue
, rtl_math_StringFormat eFormat
,
224 sal_Int32 nDecPlaces
, typename
T::Char cDecSeparator
,
225 sal_Int32
const * pGroups
,
226 typename
T::Char cGroupSeparator
,
227 bool bEraseTrailingDecZeros
)
229 static double const nRoundVal
[] = {
230 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6,
231 0.5e-7, 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14
234 // sign adjustment, instead of testing for fValue<0.0 this will also fetch
236 bool bSign
= rtl::math::isSignBitSet(fValue
);
241 if (rtl::math::isNan(fValue
))
243 // #i112652# XMLSchema-2
244 sal_Int32 nCapacity
= RTL_CONSTASCII_LENGTH("NaN");
245 if (!pResultCapacity
)
247 pResultCapacity
= &nCapacity
;
248 T::createBuffer(pResult
, pResultCapacity
);
252 T::appendAscii(pResult
, pResultCapacity
, &nResultOffset
,
253 RTL_CONSTASCII_STRINGPARAM("NaN"));
258 bool bHuge
= fValue
== HUGE_VAL
; // g++ 3.0.1 requires it this way...
259 if (bHuge
|| rtl::math::isInf(fValue
))
261 // #i112652# XMLSchema-2
262 sal_Int32 nCapacity
= RTL_CONSTASCII_LENGTH("-INF");
263 if (!pResultCapacity
)
265 pResultCapacity
= &nCapacity
;
266 T::createBuffer(pResult
, pResultCapacity
);
271 T::appendAscii(pResult
, pResultCapacity
, &nResultOffset
,
272 RTL_CONSTASCII_STRINGPARAM("-"));
274 T::appendAscii(pResult
, pResultCapacity
, &nResultOffset
,
275 RTL_CONSTASCII_STRINGPARAM("INF"));
280 // Use integer representation for integer values that fit into the
281 // mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy.
282 const sal_Int64 kMaxInt
= (static_cast< sal_Int64
>(1) << 53) - 1;
283 if ((eFormat
== rtl_math_StringFormat_Automatic
||
284 eFormat
== rtl_math_StringFormat_F
) && fValue
<= static_cast< double >(kMaxInt
))
286 sal_Int64 nInt
= static_cast< sal_Int64
>(fValue
);
287 // Check the integer range again because double comparison may yield
288 // true within the precision range.
289 if (nInt
<= kMaxInt
&& static_cast< double >(nInt
) == fValue
)
291 if (nDecPlaces
== rtl_math_DecimalPlaces_Max
)
294 nDecPlaces
= ::std::max
< sal_Int32
>(::std::min
<sal_Int32
>(nDecPlaces
, 15), -15);
296 if (bEraseTrailingDecZeros
&& nDecPlaces
> 0)
299 // Round before decimal position.
302 sal_Int64 nRounding
= static_cast< sal_Int64
>(getN10Exp(-nDecPlaces
- 1));
303 sal_Int64 nTemp
= nInt
/ nRounding
;
304 int nDigit
= nTemp
% 10;
316 // Max 1 sign, 16 integer digits, 15 group separators, 1 decimal
317 // separator, 15 decimals digits.
318 typename
T::Char aBuf
[64];
319 typename
T::Char
* pBuf
= aBuf
;
320 typename
T::Char
* p
= pBuf
;
323 size_t nGrouping
= 0;
324 sal_Int32 nGroupDigits
= 0;
327 typename
T::Char nDigit
= nInt
% 10;
330 if (pGroups
&& pGroups
[nGrouping
] == ++nGroupDigits
&& nInt
> 0 && cGroupSeparator
)
332 *p
++ = cGroupSeparator
;
333 if (pGroups
[nGrouping
+1])
342 // Reverse buffer content.
343 sal_Int32 n
= (p
- pBuf
) / 2;
344 for (sal_Int32 i
=0; i
< n
; ++i
)
346 ::std::swap( pBuf
[i
], p
[-i
-1]);
352 *p
++ = cDecSeparator
;
357 if (!pResultCapacity
)
358 T::createString(pResult
, pBuf
, p
- pBuf
);
360 T::appendChars(pResult
, pResultCapacity
, &nResultOffset
, pBuf
, p
- pBuf
);
370 // Cap nExp at a small value beyond which "fValue /= N10Exp" would lose precision (or N10Exp
371 // might even be zero); that will produce output with the decimal point in a non-normalized
372 // position, but the current quality of output for such small values is probably abysmal,
375 static_cast< int >(floor(log10(fValue
))), std::numeric_limits
<double>::min_exponent10
);
376 double const N10Exp
= getN10Exp(nExp
);
383 case rtl_math_StringFormat_Automatic
:
384 { // E or F depending on exponent magnitude
386 if (nExp
<= -15 || nExp
>= 15) // was <-16, >16 in ancient versions, which leads to inaccuracies
389 eFormat
= rtl_math_StringFormat_E
;
395 nPrec
= 15 - nExp
- 1;
396 eFormat
= rtl_math_StringFormat_F
;
401 eFormat
= rtl_math_StringFormat_F
;
405 if (nDecPlaces
== rtl_math_DecimalPlaces_Max
)
410 case rtl_math_StringFormat_G
:
411 case rtl_math_StringFormat_G1
:
412 case rtl_math_StringFormat_G2
:
413 { // G-Point, similar to sprintf %G
414 if (nDecPlaces
== rtl_math_DecimalPlaces_DefaultSignificance
)
417 if (nExp
< -4 || nExp
>= nDecPlaces
)
419 nDecPlaces
= std::max
< sal_Int32
>(1, nDecPlaces
- 1);
421 if (eFormat
== rtl_math_StringFormat_G
)
422 eFormat
= rtl_math_StringFormat_E
;
423 else if (eFormat
== rtl_math_StringFormat_G2
)
424 eFormat
= rtl_math_StringFormat_E2
;
425 else if (eFormat
== rtl_math_StringFormat_G1
)
426 eFormat
= rtl_math_StringFormat_E1
;
430 nDecPlaces
= std::max
< sal_Int32
>(0, nDecPlaces
- nExp
- 1);
431 eFormat
= rtl_math_StringFormat_F
;
439 sal_Int32 nDigits
= nDecPlaces
+ 1;
441 if (eFormat
== rtl_math_StringFormat_F
)
447 if ((fValue
+= nRoundVal
[std::min
<sal_Int32
>(nDigits
, 15)] ) >= 10)
452 if (eFormat
== rtl_math_StringFormat_F
)
457 static sal_Int32
const nBufMax
= 256;
458 typename
T::Char aBuf
[nBufMax
];
459 typename
T::Char
* pBuf
;
460 sal_Int32 nBuf
= static_cast< sal_Int32
>
461 (nDigits
<= 0 ? std::max
< sal_Int32
>(nDecPlaces
, abs(nExp
))
462 : nDigits
+ nDecPlaces
) + 10 + (pGroups
? abs(nDigits
) * 2 : 0);
466 pBuf
= static_cast< typename
T::Char
* >(
467 malloc(nBuf
* sizeof (typename
T::Char
)));
468 OSL_ENSURE(pBuf
, "Out of memory");
475 typename
T::Char
* p
= pBuf
;
477 *p
++ = static_cast< typename
T::Char
>('-');
479 bool bHasDec
= false;
482 // Check for F format and number < 1
483 if(eFormat
== rtl_math_StringFormat_F
)
487 *p
++ = static_cast< typename
T::Char
>('0');
490 *p
++ = cDecSeparator
;
494 sal_Int32 i
= (nDigits
<= 0 ? nDecPlaces
: -nExp
- 1);
498 *p
++ = static_cast< typename
T::Char
>('0');
513 int nGrouping
= 0, nGroupSelector
= 0, nGroupExceed
= 0;
514 if (nDecPos
> 1 && pGroups
&& pGroups
[0] && cGroupSeparator
)
516 while (nGrouping
+ pGroups
[nGroupSelector
] < nDecPos
)
518 nGrouping
+= pGroups
[nGroupSelector
];
519 if (pGroups
[nGroupSelector
+1])
521 if (nGrouping
+ pGroups
[nGroupSelector
+1] >= nDecPos
)
526 else if (!nGroupExceed
)
528 nGroupExceed
= nGrouping
;
536 for (int i
= 0; ; i
++)
538 if (i
< 15) // was 16 in ancient versions, which leads to inaccuracies
541 if (nDigits
-1 == 0 && i
> 0 && i
< 14)
542 nDigit
= static_cast< int >(floor( fValue
+ nCorrVal
[15-i
]));
544 nDigit
= static_cast< int >(fValue
+ 1E-15);
547 { // after-treatment of up-rounding to the next decade
548 sal_Int32 sLen
= static_cast< long >(p
-pBuf
)-1;
549 if (sLen
== -1 || (sLen
== 0 && bSign
))
551 // Assert that no one changed the logic we rely on.
552 assert(!bSign
|| *pBuf
== static_cast< typename
T::Char
>('-'));
556 if (eFormat
== rtl_math_StringFormat_F
)
558 *p
++ = static_cast< typename
T::Char
>('1');
559 *p
++ = static_cast< typename
T::Char
>('0');
563 *p
++ = static_cast< typename
T::Char
>('1');
564 *p
++ = cDecSeparator
;
565 *p
++ = static_cast< typename
T::Char
>('0');
572 for (sal_Int32 j
= sLen
; j
>= 0; j
--)
574 typename
T::Char cS
= pBuf
[j
];
577 // Do not touch leading minus sign put earlier.
578 assert(cS
== static_cast< typename
T::Char
>('-'));
579 break; // for, this is the last character backwards.
581 if (cS
!= cDecSeparator
)
583 if (cS
!= static_cast< typename
T::Char
>('9'))
586 j
= -1; // break loop
590 pBuf
[j
] = static_cast< typename
T::Char
>('0');
591 if (j
== 0 || (j
== 1 && bSign
))
593 if (eFormat
== rtl_math_StringFormat_F
)
595 typename
T::Char
* px
= p
++;
602 pBuf
[0] = static_cast< typename
T::Char
>('1');
606 pBuf
[j
] = static_cast< typename
T::Char
>('1');
614 *p
++ = static_cast< typename
T::Char
>('0');
620 *p
++ = static_cast< typename
T::Char
>(
621 nDigit
+ static_cast< typename
T::Char
>('0') );
622 fValue
= (fValue
- nDigit
) * 10.0;
627 *p
++ = static_cast< typename
T::Char
>('0');
637 *p
++ = cDecSeparator
;
640 else if (nDecPos
== nGrouping
)
642 *p
++ = cGroupSeparator
;
643 nGrouping
-= pGroups
[nGroupSelector
];
645 if (nGroupSelector
&& nGrouping
< nGroupExceed
)
652 if (!bHasDec
&& eFormat
== rtl_math_StringFormat_F
)
653 { // nDecPlaces < 0 did round the value
654 while (--nDecPos
> 0)
655 { // fill before decimal point
656 if (nDecPos
== nGrouping
)
658 *p
++ = cGroupSeparator
;
659 nGrouping
-= pGroups
[nGroupSelector
];
661 if (nGroupSelector
&& nGrouping
< nGroupExceed
)
665 *p
++ = static_cast< typename
T::Char
>('0');
669 if (bEraseTrailingDecZeros
&& bHasDec
&& p
> pBuf
)
671 while (*(p
-1) == static_cast< typename
T::Char
>('0'))
676 if (*(p
-1) == cDecSeparator
)
680 // Print the exponent ('E', followed by '+' or '-', followed by exactly
681 // three digits for rtl_math_StringFormat_E). The code in
682 // rtl_[u]str_valueOf{Float|Double} relies on this format.
683 if (eFormat
== rtl_math_StringFormat_E
|| eFormat
== rtl_math_StringFormat_E2
|| eFormat
== rtl_math_StringFormat_E1
)
686 *p
++ = static_cast< typename
T::Char
>('1');
687 // maybe no nDigits if nDecPlaces < 0
689 *p
++ = static_cast< typename
T::Char
>('E');
693 *p
++ = static_cast< typename
T::Char
>('-');
697 *p
++ = static_cast< typename
T::Char
>('+');
700 if (eFormat
== rtl_math_StringFormat_E
|| nExp
>= 100)
701 *p
++ = static_cast< typename
T::Char
>(
702 nExp
/ 100 + static_cast< typename
T::Char
>('0') );
706 if (eFormat
== rtl_math_StringFormat_E
|| eFormat
== rtl_math_StringFormat_E2
|| nExp
>= 10)
707 *p
++ = static_cast< typename
T::Char
>(
708 nExp
/ 10 + static_cast< typename
T::Char
>('0') );
710 *p
++ = static_cast< typename
T::Char
>(
711 nExp
% 10 + static_cast< typename
T::Char
>('0') );
714 if (!pResultCapacity
)
715 T::createString(pResult
, pBuf
, p
- pBuf
);
717 T::appendChars(pResult
, pResultCapacity
, &nResultOffset
, pBuf
, p
- pBuf
);
719 if (pBuf
!= &aBuf
[0])
725 void SAL_CALL
rtl_math_doubleToString(rtl_String
** pResult
,
726 sal_Int32
* pResultCapacity
,
727 sal_Int32 nResultOffset
, double fValue
,
728 rtl_math_StringFormat eFormat
,
729 sal_Int32 nDecPlaces
,
730 sal_Char cDecSeparator
,
731 sal_Int32
const * pGroups
,
732 sal_Char cGroupSeparator
,
733 sal_Bool bEraseTrailingDecZeros
)
736 doubleToString
< StringTraits
>(
737 pResult
, pResultCapacity
, nResultOffset
, fValue
, eFormat
, nDecPlaces
,
738 cDecSeparator
, pGroups
, cGroupSeparator
, bEraseTrailingDecZeros
);
741 void SAL_CALL
rtl_math_doubleToUString(rtl_uString
** pResult
,
742 sal_Int32
* pResultCapacity
,
743 sal_Int32 nResultOffset
, double fValue
,
744 rtl_math_StringFormat eFormat
,
745 sal_Int32 nDecPlaces
,
746 sal_Unicode cDecSeparator
,
747 sal_Int32
const * pGroups
,
748 sal_Unicode cGroupSeparator
,
749 sal_Bool bEraseTrailingDecZeros
)
752 doubleToString
< UStringTraits
>(
753 pResult
, pResultCapacity
, nResultOffset
, fValue
, eFormat
, nDecPlaces
,
754 cDecSeparator
, pGroups
, cGroupSeparator
, bEraseTrailingDecZeros
);
759 // if nExp * 10 + nAdd would result in overflow
760 bool long10Overflow( long& nExp
, int nAdd
)
762 if ( nExp
> (LONG_MAX
/10)
763 || (nExp
== (LONG_MAX
/10) && nAdd
> (LONG_MAX
%10)) )
771 template< typename CharT
>
772 double stringToDouble(CharT
const * pBegin
, CharT
const * pEnd
,
773 CharT cDecSeparator
, CharT cGroupSeparator
,
774 rtl_math_ConversionStatus
* pStatus
,
775 CharT
const ** pParsedEnd
)
778 rtl_math_ConversionStatus eStatus
= rtl_math_ConversionStatus_Ok
;
780 CharT
const * p0
= pBegin
;
781 while (p0
!= pEnd
&& (*p0
== CharT(' ') || *p0
== CharT('\t')))
787 if (p0
!= pEnd
&& *p0
== CharT('-'))
795 if (p0
!= pEnd
&& *p0
== CharT('+'))
799 CharT
const * p
= p0
;
802 // #i112652# XMLSchema-2
805 if ((CharT('N') == p
[0]) && (CharT('a') == p
[1])
806 && (CharT('N') == p
[2]))
809 rtl::math::setNan( &fVal
);
812 else if ((CharT('I') == p
[0]) && (CharT('N') == p
[1])
813 && (CharT('F') == p
[2]))
817 eStatus
= rtl_math_ConversionStatus_OutOfRange
;
822 if (!bDone
) // do not recognize e.g. NaN1.23
824 // Leading zeros and group separators between digits may be safely
825 // ignored. p0 < p implies that there was a leading 0 already,
826 // consecutive group separators may not happen as *(p+1) is checked for
828 while (p
!= pEnd
&& (*p
== CharT('0') || (*p
== cGroupSeparator
829 && p0
< p
&& p
+1 < pEnd
&& rtl::isAsciiDigit(*(p
+1)))))
834 CharT
const * pFirstSignificant
= ((p
> pBegin
&& *(p
-1) == CharT('0')) ? p
-1 : p
);
835 long nValExp
= 0; // carry along exponent of mantissa
837 // integer part of mantissa
838 for (; p
!= pEnd
; ++p
)
841 if (rtl::isAsciiDigit(c
))
843 fVal
= fVal
* 10.0 + static_cast< double >( c
- CharT('0') );
846 else if (c
!= cGroupSeparator
)
850 else if (p
== p0
|| (p
+1 == pEnd
) || !rtl::isAsciiDigit(*(p
+1)))
852 // A leading or trailing (not followed by a digit) group
853 // separator character is not a group separator.
858 // fraction part of mantissa
859 if (p
!= pEnd
&& *p
== cDecSeparator
)
864 while (p
!= pEnd
&& *p
== CharT('0'))
871 nValExp
= nFracExp
- 1; // no integer part => fraction exponent
873 // one decimal digit needs ld(10) ~= 3.32 bits
874 static const int nSigs
= (DBL_MANT_DIG
/ 3) + 1;
876 for (; p
!= pEnd
; ++p
)
879 if (!rtl::isAsciiDigit(c
))
884 { // further digits (more than nSigs) don't have any
886 fFrac
= fFrac
* 10.0 + static_cast<double>(c
- CharT('0'));
894 fVal
+= rtl::math::pow10Exp( fFrac
, nFracExp
);
896 else if (nValExp
< 0)
898 if (pFirstSignificant
+ 1 == p
)
900 // No digit at all, only separator(s) without integer or
901 // fraction part. Bail out. No number. No error.
906 *pParsedEnd
= pBegin
;
910 nValExp
= 0; // no digit other than 0 after decimal point
915 --nValExp
; // started with offset +1 at the first mantissa digit
918 if (p
!= p0
&& p
!= pEnd
&& (*p
== CharT('E') || *p
== CharT('e')))
920 CharT
const * const pExponent
= p
;
923 if (p
!= pEnd
&& *p
== CharT('-'))
931 if (p
!= pEnd
&& *p
== CharT('+'))
934 CharT
const * const pFirstExpDigit
= p
;
936 { // no matter what follows, zero stays zero, but carry on the
938 while (p
!= pEnd
&& rtl::isAsciiDigit(*p
))
943 if (p
== pFirstExpDigit
)
944 { // no digits in exponent, reset end of scan
950 bool bOverflow
= false;
952 for (; p
!= pEnd
; ++p
)
955 if (!rtl::isAsciiDigit(c
))
958 int i
= c
- CharT('0');
960 if ( long10Overflow( nExp
, i
) )
963 nExp
= nExp
* 10 + i
;
973 bOverflow
= o3tl::checked_add(nExp
, nValExp
, nAllExp
);
974 if ( nAllExp
> DBL_MAX_10_EXP
|| (bOverflow
&& !bExpSign
) )
977 eStatus
= rtl_math_ConversionStatus_OutOfRange
;
979 else if ((nAllExp
< DBL_MIN_10_EXP
) ||
980 (bOverflow
&& bExpSign
) )
983 eStatus
= rtl_math_ConversionStatus_OutOfRange
;
985 else if ( nExp
> DBL_MAX_10_EXP
|| nExp
< DBL_MIN_10_EXP
)
986 { // compensate exponents
987 fVal
= rtl::math::pow10Exp( fVal
, -nValExp
);
988 fVal
= rtl::math::pow10Exp( fVal
, nAllExp
);
992 fVal
= rtl::math::pow10Exp( fVal
, nExp
); // normal
995 else if (p
== pFirstExpDigit
)
996 { // no digits in exponent, reset end of scan
1001 else if (p
- p0
== 2 && p
!= pEnd
&& p
[0] == CharT('#')
1002 && p
[-1] == cDecSeparator
&& p
[-2] == CharT('1'))
1004 if (pEnd
- p
>= 4 && p
[1] == CharT('I') && p
[2] == CharT('N')
1005 && p
[3] == CharT('F'))
1007 // "1.#INF", "+1.#INF", "-1.#INF"
1010 eStatus
= rtl_math_ConversionStatus_OutOfRange
;
1011 // Eat any further digits:
1012 while (p
!= pEnd
&& rtl::isAsciiDigit(*p
))
1015 else if (pEnd
- p
>= 4 && p
[1] == CharT('N') && p
[2] == CharT('A')
1016 && p
[3] == CharT('N'))
1018 // "1.#NAN", "+1.#NAN", "-1.#NAN"
1020 rtl::math::setNan( &fVal
);
1029 m
.md
.w32_parts
.msw
|= 0x80000000; // create negative NaN
1031 bSign
= false; // don't negate again
1034 // Eat any further digits:
1035 while (p
!= pEnd
&& rtl::isAsciiDigit(*p
))
1043 // overflow also if more than DBL_MAX_10_EXP digits without decimal
1044 // separator, or 0. and more than DBL_MIN_10_EXP digits, ...
1045 bool bHuge
= fVal
== HUGE_VAL
; // g++ 3.0.1 requires it this way...
1047 eStatus
= rtl_math_ConversionStatus_OutOfRange
;
1056 *pParsedEnd
= p
== p0
? pBegin
: p
;
1063 double SAL_CALL
rtl_math_stringToDouble(sal_Char
const * pBegin
,
1064 sal_Char
const * pEnd
,
1065 sal_Char cDecSeparator
,
1066 sal_Char cGroupSeparator
,
1067 rtl_math_ConversionStatus
* pStatus
,
1068 sal_Char
const ** pParsedEnd
)
1069 SAL_THROW_EXTERN_C()
1071 return stringToDouble(
1072 reinterpret_cast<unsigned char const *>(pBegin
),
1073 reinterpret_cast<unsigned char const *>(pEnd
),
1074 static_cast<unsigned char>(cDecSeparator
),
1075 static_cast<unsigned char>(cGroupSeparator
), pStatus
,
1076 reinterpret_cast<unsigned char const **>(pParsedEnd
));
1079 double SAL_CALL
rtl_math_uStringToDouble(sal_Unicode
const * pBegin
,
1080 sal_Unicode
const * pEnd
,
1081 sal_Unicode cDecSeparator
,
1082 sal_Unicode cGroupSeparator
,
1083 rtl_math_ConversionStatus
* pStatus
,
1084 sal_Unicode
const ** pParsedEnd
)
1085 SAL_THROW_EXTERN_C()
1087 return stringToDouble(pBegin
, pEnd
, cDecSeparator
, cGroupSeparator
, pStatus
,
1091 double SAL_CALL
rtl_math_round(double fValue
, int nDecPlaces
,
1092 enum rtl_math_RoundingMode eMode
)
1093 SAL_THROW_EXTERN_C()
1095 OSL_ASSERT(nDecPlaces
>= -20 && nDecPlaces
<= 20);
1100 if ( nDecPlaces
== 0 && eMode
== rtl_math_RoundingMode_Corrected
)
1101 return std::round( fValue
);
1104 bool bSign
= rtl::math::isSignBitSet( fValue
);
1109 if (nDecPlaces
!= 0)
1111 // max 20 decimals, we don't have unlimited precision
1112 // #38810# and no overflow on fValue*=fFac
1113 if (nDecPlaces
< -20 || 20 < nDecPlaces
|| fValue
> (DBL_MAX
/ 1e20
))
1114 return bSign
? -fValue
: fValue
;
1116 fFac
= getN10Exp(nDecPlaces
);
1122 case rtl_math_RoundingMode_Corrected
:
1124 int nExp
; // exponent for correction
1126 nExp
= static_cast<int>( floor( log10( fValue
) ) );
1134 else if (nExp
>= 14)
1139 fValue
= floor(fValue
+ 0.5 + nCorrVal
[nIndex
]);
1142 case rtl_math_RoundingMode_Down
:
1143 fValue
= rtl::math::approxFloor(fValue
);
1145 case rtl_math_RoundingMode_Up
:
1146 fValue
= rtl::math::approxCeil(fValue
);
1148 case rtl_math_RoundingMode_Floor
:
1149 fValue
= bSign
? rtl::math::approxCeil(fValue
)
1150 : rtl::math::approxFloor( fValue
);
1152 case rtl_math_RoundingMode_Ceiling
:
1153 fValue
= bSign
? rtl::math::approxFloor(fValue
)
1154 : rtl::math::approxCeil(fValue
);
1156 case rtl_math_RoundingMode_HalfDown
:
1158 double f
= floor(fValue
);
1159 fValue
= ((fValue
- f
) <= 0.5) ? f
: ceil(fValue
);
1162 case rtl_math_RoundingMode_HalfUp
:
1164 double f
= floor(fValue
);
1165 fValue
= ((fValue
- f
) < 0.5) ? f
: ceil(fValue
);
1168 case rtl_math_RoundingMode_HalfEven
:
1169 #if defined FLT_ROUNDS
1171 Use fast version. FLT_ROUNDS may be defined to a function by some compilers!
1173 DBL_EPSILON is the smallest fractional number which can be represented,
1174 its reciprocal is therefore the smallest number that cannot have a
1175 fractional part. Once you add this reciprocal to `x', its fractional part
1176 is stripped off. Simply subtracting the reciprocal back out returns `x'
1177 without its fractional component.
1178 Simple, clever, and elegant - thanks to Ross Cottrell, the original author,
1179 who placed it into public domain.
1181 volatile: prevent compiler from being too smart
1183 if (FLT_ROUNDS
== 1)
1185 volatile double x
= fValue
+ 1.0 / DBL_EPSILON
;
1186 fValue
= x
- 1.0 / DBL_EPSILON
;
1189 #endif // FLT_ROUNDS
1191 double f
= floor(fValue
);
1192 if ((fValue
- f
) != 0.5)
1194 fValue
= floor( fValue
+ 0.5 );
1199 fValue
= (g
== floor( g
)) ? f
: (f
+ 1.0);
1208 if (nDecPlaces
!= 0)
1211 return bSign
? -fValue
: fValue
;
1214 double SAL_CALL
rtl_math_pow10Exp(double fValue
, int nExp
) SAL_THROW_EXTERN_C()
1216 return fValue
* getN10Exp(nExp
);
1219 double SAL_CALL
rtl_math_approxValue( double fValue
) SAL_THROW_EXTERN_C()
1221 const double fBigInt
= 2199023255552.0; // 2^41 -> only 11 bits left for fractional part, fine as decimal
1222 if (fValue
== 0.0 || fValue
== HUGE_VAL
|| !::rtl::math::isFinite( fValue
) || fValue
> fBigInt
)
1224 // We don't handle these conditions. Bail out.
1228 double fOrigValue
= fValue
;
1230 bool bSign
= ::rtl::math::isSignBitSet(fValue
);
1234 // If the value is either integer representable as double,
1235 // or only has small number of bits in fraction part, then we need not do any approximation
1236 if (isRepresentableInteger(fValue
) || getBitsInFracPart(fValue
) <= 11)
1239 int nExp
= static_cast< int >(floor(log10(fValue
)));
1241 double fExpValue
= getN10Exp(nExp
);
1243 fValue
*= fExpValue
;
1244 // If the original value was near DBL_MIN we got an overflow. Restore and
1246 if (!rtl::math::isFinite(fValue
))
1249 fValue
= rtl_math_round(fValue
, 0, rtl_math_RoundingMode_Corrected
);
1250 fValue
/= fExpValue
;
1252 // If the original value was near DBL_MAX we got an overflow. Restore and
1254 if (!rtl::math::isFinite(fValue
))
1257 return bSign
? -fValue
: fValue
;
1260 bool SAL_CALL
rtl_math_approxEqual(double a
, double b
) SAL_THROW_EXTERN_C()
1262 static const double e48
= 1.0 / (16777216.0 * 16777216.0);
1263 static const double e44
= e48
* 16.0;
1268 if (a
== 0.0 || b
== 0.0)
1271 const double d
= fabs(a
- b
);
1272 if (!rtl::math::isFinite(d
))
1273 return false; // Nan or Inf involved
1275 if (d
> ((a
= fabs(a
)) * e44
) || d
> ((b
= fabs(b
)) * e44
))
1278 if (isRepresentableInteger(d
) && isRepresentableInteger(a
) && isRepresentableInteger(b
))
1279 return false; // special case for representable integers.
1281 return (d
< a
* e48
&& d
< b
* e48
);
1284 double SAL_CALL
rtl_math_expm1(double fValue
) SAL_THROW_EXTERN_C()
1286 return expm1(fValue
);
1289 double SAL_CALL
rtl_math_log1p(double fValue
) SAL_THROW_EXTERN_C()
1293 return fValue
; // macOS 10.8 libc returns 0.0 for -0.0
1296 return log1p(fValue
);
1299 double SAL_CALL
rtl_math_atanh(double fValue
) SAL_THROW_EXTERN_C()
1300 #if defined __clang__
1301 __attribute__((no_sanitize("float-divide-by-zero"))) // atahn(1) -> inf
1304 return 0.5 * rtl_math_log1p(2.0 * fValue
/ (1.0-fValue
));
1307 /** Parent error function (erf) */
1308 double SAL_CALL
rtl_math_erf(double x
) SAL_THROW_EXTERN_C()
1313 /** Parent complementary error function (erfc) */
1314 double SAL_CALL
rtl_math_erfc(double x
) SAL_THROW_EXTERN_C()
1319 /** improved accuracy of asinh for |x| large and for x near zero
1322 double SAL_CALL
rtl_math_asinh(double fX
) SAL_THROW_EXTERN_C()
1335 return fSign
* rtl_math_log1p( fX
+ fX
*fX
/ (1.0 + sqrt( 1.0 + fX
*fX
)));
1338 return fSign
* log( fX
+ sqrt( 1.0 + fX
*fX
));
1340 return fSign
* log( 2.0*fX
);
1343 /** improved accuracy of acosh for x large and for x near 1
1346 double SAL_CALL
rtl_math_acosh(double fX
) SAL_THROW_EXTERN_C()
1348 volatile double fZ
= fX
- 1.0;
1352 ::rtl::math::setNan( &fResult
);
1359 return rtl_math_log1p( fZ
+ sqrt( fZ
*fZ
+ 2.0*fZ
));
1362 return log( fX
+ sqrt( fX
*fX
- 1.0));
1364 return log( 2.0*fX
);
1367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */