bump product version to 6.3.0.0.beta1
[LibreOffice.git] / include / rtl / math.hxx
bloba965c7b38bca43dcd6d83de1f978240f0d2bd393
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #ifndef INCLUDED_RTL_MATH_HXX
21 #define INCLUDED_RTL_MATH_HXX
23 #include "rtl/math.h"
24 #include "rtl/strbuf.hxx"
25 #include "rtl/string.hxx"
26 #include "rtl/ustring.hxx"
27 #include "rtl/ustrbuf.hxx"
28 #include "sal/mathconf.h"
29 #include "sal/types.h"
31 #include <cstddef>
32 #include <math.h>
34 namespace rtl {
36 namespace math {
38 /** A wrapper around rtl_math_doubleToString.
40 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
41 sal_Int32 nDecPlaces,
42 sal_Char cDecSeparator,
43 sal_Int32 const * pGroups,
44 sal_Char cGroupSeparator,
45 bool bEraseTrailingDecZeros = false)
47 rtl::OString aResult;
48 rtl_math_doubleToString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
49 cDecSeparator, pGroups, cGroupSeparator,
50 bEraseTrailingDecZeros);
51 return aResult;
54 /** A wrapper around rtl_math_doubleToString, with no grouping.
56 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
57 sal_Int32 nDecPlaces,
58 sal_Char cDecSeparator,
59 bool bEraseTrailingDecZeros = false)
61 rtl::OString aResult;
62 rtl_math_doubleToString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
63 cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
64 return aResult;
67 /** A wrapper around rtl_math_doubleToString that appends to an
68 rtl::OStringBuffer.
70 @since LibreOffice 5.4
72 inline void doubleToStringBuffer(
73 rtl::OStringBuffer& rBuffer, double fValue, rtl_math_StringFormat eFormat,
74 sal_Int32 nDecPlaces, sal_Char cDecSeparator, sal_Int32 const * pGroups,
75 sal_Char cGroupSeparator, bool bEraseTrailingDecZeros = false)
77 rtl_String ** pData;
78 sal_Int32 * pCapacity;
79 rBuffer.accessInternals(&pData, &pCapacity);
80 rtl_math_doubleToString(
81 pData, pCapacity, rBuffer.getLength(), fValue, eFormat, nDecPlaces,
82 cDecSeparator, pGroups, cGroupSeparator, bEraseTrailingDecZeros);
85 /** A wrapper around rtl_math_doubleToString that appends to an
86 rtl::OStringBuffer, with no grouping.
88 @since LibreOffice 5.4
90 inline void doubleToStringBuffer(
91 rtl::OStringBuffer& rBuffer, double fValue, rtl_math_StringFormat eFormat,
92 sal_Int32 nDecPlaces, sal_Char cDecSeparator,
93 bool bEraseTrailingDecZeros = false)
95 rtl_String ** pData;
96 sal_Int32 * pCapacity;
97 rBuffer.accessInternals(&pData, &pCapacity);
98 rtl_math_doubleToString(
99 pData, pCapacity, rBuffer.getLength(), fValue, eFormat, nDecPlaces,
100 cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
103 /** A wrapper around rtl_math_doubleToUString.
105 inline rtl::OUString doubleToUString(double fValue,
106 rtl_math_StringFormat eFormat,
107 sal_Int32 nDecPlaces,
108 sal_Unicode cDecSeparator,
109 sal_Int32 const * pGroups,
110 sal_Unicode cGroupSeparator,
111 bool bEraseTrailingDecZeros = false)
113 rtl::OUString aResult;
114 rtl_math_doubleToUString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
115 cDecSeparator, pGroups, cGroupSeparator,
116 bEraseTrailingDecZeros);
117 return aResult;
120 /** A wrapper around rtl_math_doubleToUString, with no grouping.
122 inline rtl::OUString doubleToUString(double fValue,
123 rtl_math_StringFormat eFormat,
124 sal_Int32 nDecPlaces,
125 sal_Unicode cDecSeparator,
126 bool bEraseTrailingDecZeros = false)
128 rtl::OUString aResult;
129 rtl_math_doubleToUString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
130 cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
131 return aResult;
134 /** A wrapper around rtl_math_doubleToUString that appends to an
135 rtl::OUStringBuffer.
137 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
138 rtl_math_StringFormat eFormat,
139 sal_Int32 nDecPlaces,
140 sal_Unicode cDecSeparator,
141 sal_Int32 const * pGroups,
142 sal_Unicode cGroupSeparator,
143 bool bEraseTrailingDecZeros = false)
145 rtl_uString ** pData;
146 sal_Int32 * pCapacity;
147 rBuffer.accessInternals( &pData, &pCapacity );
148 rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
149 eFormat, nDecPlaces, cDecSeparator, pGroups,
150 cGroupSeparator, bEraseTrailingDecZeros);
153 /** A wrapper around rtl_math_doubleToUString that appends to an
154 rtl::OUStringBuffer, with no grouping.
156 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
157 rtl_math_StringFormat eFormat,
158 sal_Int32 nDecPlaces,
159 sal_Unicode cDecSeparator,
160 bool bEraseTrailingDecZeros = false)
162 rtl_uString ** pData;
163 sal_Int32 * pCapacity;
164 rBuffer.accessInternals( &pData, &pCapacity );
165 rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
166 eFormat, nDecPlaces, cDecSeparator, NULL, 0,
167 bEraseTrailingDecZeros);
170 /** A wrapper around rtl_math_stringToDouble.
172 inline double stringToDouble(rtl::OString const & rString,
173 sal_Char cDecSeparator, sal_Char cGroupSeparator,
174 rtl_math_ConversionStatus * pStatus = NULL,
175 sal_Int32 * pParsedEnd = NULL)
177 sal_Char const * pBegin = rString.getStr();
178 sal_Char const * pEnd;
179 double fResult = rtl_math_stringToDouble(pBegin,
180 pBegin + rString.getLength(),
181 cDecSeparator, cGroupSeparator,
182 pStatus, &pEnd);
183 if (pParsedEnd != NULL)
184 *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
185 return fResult;
188 /** A wrapper around rtl_math_uStringToDouble.
190 inline double stringToDouble(rtl::OUString const & rString,
191 sal_Unicode cDecSeparator,
192 sal_Unicode cGroupSeparator,
193 rtl_math_ConversionStatus * pStatus = NULL,
194 sal_Int32 * pParsedEnd = NULL)
196 sal_Unicode const * pBegin = rString.getStr();
197 sal_Unicode const * pEnd;
198 double fResult = rtl_math_uStringToDouble(pBegin,
199 pBegin + rString.getLength(),
200 cDecSeparator, cGroupSeparator,
201 pStatus, &pEnd);
202 if (pParsedEnd != NULL)
203 *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
204 return fResult;
207 /** A wrapper around rtl_math_round.
209 inline double round(
210 double fValue, int nDecPlaces = 0,
211 rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected)
213 return rtl_math_round(fValue, nDecPlaces, eMode);
216 /** A wrapper around rtl_math_pow10Exp.
218 inline double pow10Exp(double fValue, int nExp)
220 return rtl_math_pow10Exp(fValue, nExp);
223 /** A wrapper around rtl_math_approxValue.
225 inline double approxValue(double fValue)
227 return rtl_math_approxValue(fValue);
230 /** A wrapper around rtl_math_expm1.
232 inline double expm1(double fValue)
234 return rtl_math_expm1(fValue);
237 /** A wrapper around rtl_math_log1p.
239 inline double log1p(double fValue)
241 return rtl_math_log1p(fValue);
244 /** A wrapper around rtl_math_atanh.
246 inline double atanh(double fValue)
248 return rtl_math_atanh(fValue);
251 /** A wrapper around rtl_math_erf.
253 inline double erf(double fValue)
255 return rtl_math_erf(fValue);
258 /** A wrapper around rtl_math_erfc.
260 inline double erfc(double fValue)
262 return rtl_math_erfc(fValue);
265 /** A wrapper around rtl_math_asinh.
267 inline double asinh(double fValue)
269 return rtl_math_asinh(fValue);
272 /** A wrapper around rtl_math_acosh.
274 inline double acosh(double fValue)
276 return rtl_math_acosh(fValue);
279 /** A wrapper around rtl_math_approxEqual.
281 inline bool approxEqual(double a, double b)
283 return rtl_math_approxEqual( a, b );
286 /** Test equality of two values with an accuracy defined by nPrec
288 @attention
289 approxEqual( value!=0.0, 0.0 ) _never_ yields true.
291 inline bool approxEqual(double a, double b, sal_Int16 nPrec)
293 if ( a == b )
294 return true;
295 double x = a - b;
296 return (x < 0.0 ? -x : x)
297 < ((a < 0.0 ? -a : a) * (1.0 / (pow(2.0, nPrec))));
300 /** Add two values.
302 If signs differ and the absolute values are equal according to approxEqual()
303 the method returns 0.0 instead of calculating the sum.
305 If you wanted to sum up multiple values it would be convenient not to call
306 approxAdd() for each value but instead remember the first value not equal to
307 0.0, add all other values using normal + operator, and with the result and
308 the remembered value call approxAdd().
310 inline double approxAdd(double a, double b)
312 if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
313 && approxEqual( a, -b ) )
314 return 0.0;
315 return a + b;
318 /** Subtract two values (a-b).
320 If signs are identical and the values are equal according to approxEqual()
321 the method returns 0.0 instead of calculating the subtraction.
323 inline double approxSub(double a, double b)
325 if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
326 return 0.0;
327 return a - b;
330 /** floor() method taking approxValue() into account.
332 Use for expected integer values being calculated by double functions.
334 inline double approxFloor(double a)
336 return floor( approxValue( a ));
339 /** ceil() method taking approxValue() into account.
341 Use for expected integer values being calculated by double functions.
343 inline double approxCeil(double a)
345 return ceil( approxValue( a ));
348 /** Tests whether a value is neither INF nor NAN.
350 inline bool isFinite(double d)
352 return SAL_MATH_FINITE(d);
355 /** If a value represents +INF or -INF.
357 The sign bit may be queried with isSignBitSet().
359 If isFinite(d)==false and isInf(d)==false then NAN.
361 inline bool isInf(double d)
363 // exponent==0x7ff fraction==0
364 return !SAL_MATH_FINITE(d) &&
365 (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
366 && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
367 == 0);
370 /** Test on any QNAN or SNAN.
372 inline bool isNan(double d)
374 // exponent==0x7ff fraction!=0
375 return !SAL_MATH_FINITE(d) && (
376 (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
377 || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
378 != 0) );
381 /** If the sign bit is set.
383 inline bool isSignBitSet(double d)
385 return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
388 /** Set to +INF if bNegative==false or -INF if bNegative==true.
390 inline void setInf(double * pd, bool bNegative)
392 union
394 double sd;
395 sal_math_Double md;
397 md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
398 md.w32_parts.lsw = 0;
399 *pd = sd;
402 /** Set a QNAN.
404 inline void setNan(double * pd)
406 union
408 double sd;
409 sal_math_Double md;
411 md.w32_parts.msw = 0x7FFFFFFF;
412 md.w32_parts.lsw = 0xFFFFFFFF;
413 *pd = sd;
416 /** If a value is a valid argument for sin(), cos(), tan().
418 IEEE 754 specifies that absolute values up to 2^64 (=1.844e19) for the
419 radian must be supported by trigonometric functions. Unfortunately, at
420 least on x86 architectures, the FPU doesn't generate an error pattern for
421 values >2^64 but produces erroneous results instead and sets only the
422 "invalid operation" (IM) flag in the status word :-( Thus the application
423 has to handle it itself.
425 inline bool isValidArcArg(double d)
427 return fabs(d)
428 <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
429 * static_cast< double >(static_cast< unsigned long >(0x80000000))
430 * 2);
433 /** Safe sin(), returns NAN if not valid.
435 inline double sin(double d)
437 if ( isValidArcArg( d ) )
438 return ::sin( d );
439 setNan( &d );
440 return d;
443 /** Safe cos(), returns NAN if not valid.
445 inline double cos(double d)
447 if ( isValidArcArg( d ) )
448 return ::cos( d );
449 setNan( &d );
450 return d;
453 /** Safe tan(), returns NAN if not valid.
455 inline double tan(double d)
457 if ( isValidArcArg( d ) )
458 return ::tan( d );
459 setNan( &d );
460 return d;
467 #endif // INCLUDED_RTL_MATH_HXX
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */