LibreOfficeDev
LibreOfficeDev 26.8 SDK C/C++ API Reference
math.hxx
Go to the documentation of this file.
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 /*
21  * This file is part of LibreOffice published API.
22  */
23 
24 #ifndef INCLUDED_RTL_MATH_HXX
25 #define INCLUDED_RTL_MATH_HXX
26 
27 #include "rtl/math.h"
28 #include "rtl/strbuf.hxx"
29 #include "rtl/string.hxx"
30 #include "rtl/ustring.hxx"
31 #include "rtl/ustrbuf.hxx"
32 #include "sal/mathconf.h"
33 #include "sal/types.h"
34 
35 #include <cstddef>
36 #include <math.h>
37 
38 namespace rtl {
39 
40 namespace math {
41 
44 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
45  sal_Int32 nDecPlaces,
46  char cDecSeparator,
47  sal_Int32 const * pGroups,
48  char cGroupSeparator,
49  bool bEraseTrailingDecZeros = false)
50 {
51  rtl::OString aResult;
52  rtl_math_doubleToString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
53  cDecSeparator, pGroups, cGroupSeparator,
54  bEraseTrailingDecZeros);
55  return aResult;
56 }
57 
60 inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
61  sal_Int32 nDecPlaces,
62  char cDecSeparator,
63  bool bEraseTrailingDecZeros = false)
64 {
65  rtl::OString aResult;
66  rtl_math_doubleToString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
67  cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
68  return aResult;
69 }
70 
77  rtl::OStringBuffer& rBuffer, double fValue, rtl_math_StringFormat eFormat,
78  sal_Int32 nDecPlaces, char cDecSeparator, sal_Int32 const * pGroups,
79  char cGroupSeparator, bool bEraseTrailingDecZeros = false)
80 {
81  rtl_String ** pData;
82  sal_Int32 * pCapacity;
83  rBuffer.accessInternals(&pData, &pCapacity);
85  pData, pCapacity, rBuffer.getLength(), fValue, eFormat, nDecPlaces,
86  cDecSeparator, pGroups, cGroupSeparator, bEraseTrailingDecZeros);
87 }
88 
95  rtl::OStringBuffer& rBuffer, double fValue, rtl_math_StringFormat eFormat,
96  sal_Int32 nDecPlaces, char cDecSeparator,
97  bool bEraseTrailingDecZeros = false)
98 {
99  rtl_String ** pData;
100  sal_Int32 * pCapacity;
101  rBuffer.accessInternals(&pData, &pCapacity);
103  pData, pCapacity, rBuffer.getLength(), fValue, eFormat, nDecPlaces,
104  cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
105 }
106 
109 inline rtl::OUString doubleToUString(double fValue,
110  rtl_math_StringFormat eFormat,
111  sal_Int32 nDecPlaces,
112  sal_Unicode cDecSeparator,
113  sal_Int32 const * pGroups,
114  sal_Unicode cGroupSeparator,
115  bool bEraseTrailingDecZeros = false)
116 {
117  rtl::OUString aResult;
118  rtl_math_doubleToUString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
119  cDecSeparator, pGroups, cGroupSeparator,
120  bEraseTrailingDecZeros);
121  return aResult;
122 }
123 
126 inline rtl::OUString doubleToUString(double fValue,
127  rtl_math_StringFormat eFormat,
128  sal_Int32 nDecPlaces,
129  sal_Unicode cDecSeparator,
130  bool bEraseTrailingDecZeros = false)
131 {
132  rtl::OUString aResult;
133  rtl_math_doubleToUString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
134  cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
135  return aResult;
136 }
137 
141 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
142  rtl_math_StringFormat eFormat,
143  sal_Int32 nDecPlaces,
144  sal_Unicode cDecSeparator,
145  sal_Int32 const * pGroups,
146  sal_Unicode cGroupSeparator,
147  bool bEraseTrailingDecZeros = false)
148 {
149  rtl_uString ** pData;
150  sal_Int32 * pCapacity;
151  rBuffer.accessInternals( &pData, &pCapacity );
152  rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
153  eFormat, nDecPlaces, cDecSeparator, pGroups,
154  cGroupSeparator, bEraseTrailingDecZeros);
155 }
156 
160 inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
161  rtl_math_StringFormat eFormat,
162  sal_Int32 nDecPlaces,
163  sal_Unicode cDecSeparator,
164  bool bEraseTrailingDecZeros = false)
165 {
166  rtl_uString ** pData;
167  sal_Int32 * pCapacity;
168  rBuffer.accessInternals( &pData, &pCapacity );
169  rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
170  eFormat, nDecPlaces, cDecSeparator, NULL, 0,
171  bEraseTrailingDecZeros);
172 }
173 
176 #ifdef LIBO_INTERNAL_ONLY
177 inline double stringToDouble(std::string_view aString,
178  char cDecSeparator, char cGroupSeparator,
179  rtl_math_ConversionStatus * pStatus = NULL,
180  sal_Int32 * pParsedEnd = NULL)
181 {
182  char const * pBegin = aString.data();
183  char const * pEnd;
184  double fResult = rtl_math_stringToDouble(pBegin,
185  pBegin + aString.size(),
186  cDecSeparator, cGroupSeparator,
187  pStatus, &pEnd);
188  if (pParsedEnd != NULL)
189  *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
190  return fResult;
191 }
192 #else
193 inline double stringToDouble(rtl::OString const & rString,
194  char cDecSeparator, char cGroupSeparator,
195  rtl_math_ConversionStatus * pStatus = NULL,
196  sal_Int32 * pParsedEnd = NULL)
197 {
198  char const * pBegin = rString.getStr();
199  char const * pEnd;
200  double fResult = rtl_math_stringToDouble(pBegin,
201  pBegin + rString.getLength(),
202  cDecSeparator, cGroupSeparator,
203  pStatus, &pEnd);
204  if (pParsedEnd != NULL)
205  *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
206  return fResult;
207 }
208 #endif
209 
210 
213 #ifdef LIBO_INTERNAL_ONLY
214 inline double stringToDouble(std::u16string_view aString,
215  sal_Unicode cDecSeparator,
216  sal_Unicode cGroupSeparator,
217  rtl_math_ConversionStatus * pStatus = NULL,
218  sal_Int32 * pParsedEnd = NULL)
219 {
220  sal_Unicode const * pBegin = aString.data();
221  sal_Unicode const * pEnd;
222  double fResult = rtl_math_uStringToDouble(pBegin,
223  pBegin + aString.size(),
224  cDecSeparator, cGroupSeparator,
225  pStatus, &pEnd);
226  if (pParsedEnd != NULL)
227  *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
228  return fResult;
229 }
230 #else
231 inline double stringToDouble(rtl::OUString const & rString,
232  sal_Unicode cDecSeparator,
233  sal_Unicode cGroupSeparator,
234  rtl_math_ConversionStatus * pStatus = NULL,
235  sal_Int32 * pParsedEnd = NULL)
236 {
237  sal_Unicode const * pBegin = rString.getStr();
238  sal_Unicode const * pEnd;
239  double fResult = rtl_math_uStringToDouble(pBegin,
240  pBegin + rString.getLength(),
241  cDecSeparator, cGroupSeparator,
242  pStatus, &pEnd);
243  if (pParsedEnd != NULL)
244  *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
245  return fResult;
246 }
247 #endif
248 
251 inline double round(
252  double fValue, int nDecPlaces = 0,
254 {
255  return rtl_math_round(fValue, nDecPlaces, eMode);
256 }
257 
260 inline double pow10Exp(double fValue, int nExp)
261 {
262  return rtl_math_pow10Exp(fValue, nExp);
263 }
264 
267 inline double approxValue(double fValue)
268 {
269  return rtl_math_approxValue(fValue);
270 }
271 
272 inline double approxDiff(double a, double b)
273 {
274  return rtl_math_approxDiff(a, b);
275 }
276 
279 inline double expm1(double fValue)
280 {
281  return rtl_math_expm1(fValue);
282 }
283 
286 inline double log1p(double fValue)
287 {
288  return rtl_math_log1p(fValue);
289 }
290 
293 inline double atanh(double fValue)
294 {
295  return rtl_math_atanh(fValue);
296 }
297 
300 inline double erf(double fValue)
301 {
302  return rtl_math_erf(fValue);
303 }
304 
307 inline double erfc(double fValue)
308 {
309  return rtl_math_erfc(fValue);
310 }
311 
314 inline double asinh(double fValue)
315 {
316  return rtl_math_asinh(fValue);
317 }
318 
321 inline double acosh(double fValue)
322 {
323  return rtl_math_acosh(fValue);
324 }
325 
328 inline bool approxEqual(double a, double b)
329 {
330  return rtl_math_approxEqual( a, b );
331 }
332 
338 inline bool approxEqual(double a, double b, sal_Int16 nPrec)
339 {
340  if ( a == b )
341  return true;
342  double x = a - b;
343  return (x < 0.0 ? -x : x)
344  < ((a < 0.0 ? -a : a) * (1.0 / (pow(2.0, nPrec))));
345 }
346 
357 inline double approxAdd(double a, double b)
358 {
359  if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
360  && approxEqual( a, -b ) )
361  return 0.0;
362  return a + b;
363 }
364 
370 inline double approxSub(double a, double b)
371 {
372  if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
373  return 0.0;
374  return a - b;
375 }
376 
381 inline double approxFloor(double a)
382 {
383  return floor( approxValue( a ));
384 }
385 
390 inline double approxCeil(double a)
391 {
392  return ceil( approxValue( a ));
393 }
394 
397 inline bool isFinite(double d)
398 {
399  return SAL_MATH_FINITE(d);
400 }
401 
408 inline bool isInf(double d)
409 {
410  // exponent==0x7ff fraction==0
411  return !SAL_MATH_FINITE(d) &&
412  (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
413  && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
414  == 0);
415 }
416 
419 inline bool isNan(double d)
420 {
421  // exponent==0x7ff fraction!=0
422  return !SAL_MATH_FINITE(d) && (
423  (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
424  || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
425  != 0) );
426 }
427 
430 inline bool isSignBitSet(double d)
431 {
432  return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
433 }
434 
437 inline void setInf(double * pd, bool bNegative)
438 {
439  sal_math_Double& md = *reinterpret_cast<sal_math_Double*>(pd);
440  md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
441  md.w32_parts.lsw = 0;
442 }
443 
446 inline void setNan(double * pd)
447 {
448  sal_math_Double& md = *reinterpret_cast<sal_math_Double*>(pd);
449  md.w32_parts.msw = 0x7FFFFFFF;
450  md.w32_parts.lsw = 0xFFFFFFFF;
451 }
452 
462 inline bool isValidArcArg(double d)
463 {
464  return fabs(d)
465  <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
466  * static_cast< double >(static_cast< unsigned long >(0x80000000))
467  * 4);
468 }
469 
472 inline double sin(double d)
473 {
474  if ( isValidArcArg( d ) )
475  return ::sin( d );
476  setNan( &d );
477  return d;
478 }
479 
482 inline double cos(double d)
483 {
484  if ( isValidArcArg( d ) )
485  return ::cos( d );
486  setNan( &d );
487  return d;
488 }
489 
492 inline double tan(double d)
493 {
494  if ( isValidArcArg( d ) )
495  return ::tan( d );
496  setNan( &d );
497  return d;
498 }
499 
500 }
501 
502 }
503 
504 #endif // INCLUDED_RTL_MATH_HXX
505 
506 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 sal_Unicode
Definition: types.h:123
SAL_DLLPUBLIC double rtl_math_erf(double fValue) SAL_THROW_EXTERN_C()
Returns values of the Errorfunction erf.
rtl_math_RoundingMode
Rounding modes for rtl_math_round.
Definition: math.h:105
@ rtl_math_RoundingMode_Corrected
Like HalfUp, but corrects roundoff errors, preferred.
Definition: math.h:108
rtl_math_ConversionStatus
Status for rtl_math_stringToDouble and rtl_math_uStringToDouble.
Definition: math.h:88
SAL_DLLPUBLIC double rtl_math_round(double fValue, int nDecPlaces, enum rtl_math_RoundingMode eMode) SAL_THROW_EXTERN_C()
Rounds a double value.
SAL_DLLPUBLIC void rtl_math_doubleToUString(rtl_uString **pResult, sal_Int32 *pResultCapacity, sal_Int32 nResultOffset, double fValue, enum rtl_math_StringFormat eFormat, sal_Int32 nDecPlaces, sal_Unicode cDecSeparator, sal_Int32 const *pGroups, sal_Unicode cGroupSeparator, sal_Bool bEraseTrailingDecZeros) SAL_THROW_EXTERN_C()
Conversions analogous to sprintf() using internal rounding.
rtl_math_StringFormat
Formatting modes for rtl_math_doubleToString and rtl_math_doubleToUString and rtl_math_doubleToUStrin...
Definition: math.h:41
SAL_DLLPUBLIC double rtl_math_asinh(double fValue) SAL_THROW_EXTERN_C()
Returns values of the inverse hyperbolic sine.
SAL_DLLPUBLIC void rtl_math_doubleToString(rtl_String **pResult, sal_Int32 *pResultCapacity, sal_Int32 nResultOffset, double fValue, enum rtl_math_StringFormat eFormat, sal_Int32 nDecPlaces, char cDecSeparator, sal_Int32 const *pGroups, char cGroupSeparator, sal_Bool bEraseTrailingDecZeros) SAL_THROW_EXTERN_C()
Conversions analogous to sprintf() using internal rounding.
SAL_DLLPUBLIC double rtl_math_erfc(double fValue) SAL_THROW_EXTERN_C()
Returns values of the complement Errorfunction erfc.
SAL_DLLPUBLIC double rtl_math_atanh(double fValue) SAL_THROW_EXTERN_C()
Returns more accurate atanh(x) for x near 0 than calculating 0.5*log((1+x)/(1-x)).
SAL_DLLPUBLIC double rtl_math_approxValue(double fValue) SAL_THROW_EXTERN_C()
Rounds value to 15 significant decimal digits.
SAL_DLLPUBLIC bool rtl_math_approxEqual(double a, double b) SAL_THROW_EXTERN_C()
Test equality of two values with an accuracy of the magnitude of the given values scaled by 2^-48 (4 ...
SAL_DLLPUBLIC double rtl_math_stringToDouble(char const *pBegin, char const *pEnd, char cDecSeparator, char cGroupSeparator, enum rtl_math_ConversionStatus *pStatus, char const **pParsedEnd) SAL_THROW_EXTERN_C()
Conversion analogous to strtod(), convert a string representing a decimal number into a double value.
SAL_DLLPUBLIC double rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C()
Scales fVal to a power of 10 without calling pow() or div() for nExp values between -16 and +16,...
SAL_DLLPUBLIC double rtl_math_approxDiff(double a, double b) SAL_THROW_EXTERN_C()
Calculate a-b trying to diminish precision errors such as for 0.11-0.12 not return -0....
SAL_DLLPUBLIC double rtl_math_log1p(double fValue) SAL_THROW_EXTERN_C()
Returns more accurate log(1+x) for x near 0 than calculating directly.
SAL_DLLPUBLIC double rtl_math_acosh(double fValue) SAL_THROW_EXTERN_C()
Returns values of the inverse hyperbolic cosine.
SAL_DLLPUBLIC double rtl_math_expm1(double fValue) SAL_THROW_EXTERN_C()
Returns more accurate e^x-1 for x near 0 than calculating directly.
SAL_DLLPUBLIC double rtl_math_uStringToDouble(sal_Unicode const *pBegin, sal_Unicode const *pEnd, sal_Unicode cDecSeparator, sal_Unicode cGroupSeparator, enum rtl_math_ConversionStatus *pStatus, sal_Unicode const **pParsedEnd) SAL_THROW_EXTERN_C()
Conversion analogous to strtod(), convert a string representing a decimal number into a double value.
Definition: bootstrap.hxx:34
bool approxEqual(double a, double b)
A wrapper around rtl_math_approxEqual.
Definition: math.hxx:328
double approxAdd(double a, double b)
Add two values.
Definition: math.hxx:357
bool isNan(double d)
Test on any QNAN or SNAN.
Definition: math.hxx:419
double sin(double d)
Safe sin(), returns NAN if not valid.
Definition: math.hxx:472
double log1p(double fValue)
A wrapper around rtl_math_log1p.
Definition: math.hxx:286
double erf(double fValue)
A wrapper around rtl_math_erf.
Definition: math.hxx:300
double approxSub(double a, double b)
Subtract two values (a-b).
Definition: math.hxx:370
double stringToDouble(rtl::OString const &rString, char cDecSeparator, char cGroupSeparator, rtl_math_ConversionStatus *pStatus=NULL, sal_Int32 *pParsedEnd=NULL)
A wrapper around rtl_math_stringToDouble.
Definition: math.hxx:193
double approxFloor(double a)
floor() method taking approxValue() into account.
Definition: math.hxx:381
double asinh(double fValue)
A wrapper around rtl_math_asinh.
Definition: math.hxx:314
bool isValidArcArg(double d)
If a value is a valid argument for sin(), cos(), tan().
Definition: math.hxx:462
void setNan(double *pd)
Set a QNAN.
Definition: math.hxx:446
double approxDiff(double a, double b)
Definition: math.hxx:272
double expm1(double fValue)
A wrapper around rtl_math_expm1.
Definition: math.hxx:279
rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat, sal_Int32 nDecPlaces, char cDecSeparator, sal_Int32 const *pGroups, char cGroupSeparator, bool bEraseTrailingDecZeros=false)
A wrapper around rtl_math_doubleToString.
Definition: math.hxx:44
void doubleToUStringBuffer(rtl::OUStringBuffer &rBuffer, double fValue, rtl_math_StringFormat eFormat, sal_Int32 nDecPlaces, sal_Unicode cDecSeparator, sal_Int32 const *pGroups, sal_Unicode cGroupSeparator, bool bEraseTrailingDecZeros=false)
A wrapper around rtl_math_doubleToUString that appends to an rtl::OUStringBuffer.
Definition: math.hxx:141
rtl::OUString doubleToUString(double fValue, rtl_math_StringFormat eFormat, sal_Int32 nDecPlaces, sal_Unicode cDecSeparator, sal_Int32 const *pGroups, sal_Unicode cGroupSeparator, bool bEraseTrailingDecZeros=false)
A wrapper around rtl_math_doubleToUString.
Definition: math.hxx:109
double round(double fValue, int nDecPlaces=0, rtl_math_RoundingMode eMode=rtl_math_RoundingMode_Corrected)
A wrapper around rtl_math_round.
Definition: math.hxx:251
bool isInf(double d)
If a value represents +INF or -INF.
Definition: math.hxx:408
double erfc(double fValue)
A wrapper around rtl_math_erfc.
Definition: math.hxx:307
double approxValue(double fValue)
A wrapper around rtl_math_approxValue.
Definition: math.hxx:267
void doubleToStringBuffer(rtl::OStringBuffer &rBuffer, double fValue, rtl_math_StringFormat eFormat, sal_Int32 nDecPlaces, char cDecSeparator, sal_Int32 const *pGroups, char cGroupSeparator, bool bEraseTrailingDecZeros=false)
A wrapper around rtl_math_doubleToString that appends to an rtl::OStringBuffer.
Definition: math.hxx:76
double atanh(double fValue)
A wrapper around rtl_math_atanh.
Definition: math.hxx:293
bool isSignBitSet(double d)
If the sign bit is set.
Definition: math.hxx:430
void setInf(double *pd, bool bNegative)
Set to +INF if bNegative==false or -INF if bNegative==true.
Definition: math.hxx:437
double tan(double d)
Safe tan(), returns NAN if not valid.
Definition: math.hxx:492
double acosh(double fValue)
A wrapper around rtl_math_acosh.
Definition: math.hxx:321
double pow10Exp(double fValue, int nExp)
A wrapper around rtl_math_pow10Exp.
Definition: math.hxx:260
bool isFinite(double d)
Tests whether a value is neither INF nor NAN.
Definition: math.hxx:397
double approxCeil(double a)
ceil() method taking approxValue() into account.
Definition: math.hxx:390
double cos(double d)
Safe cos(), returns NAN if not valid.
Definition: math.hxx:482
A string buffer implements a mutable sequence of characters.
Definition: strbuf.hxx:72
void accessInternals(rtl_String ***pInternalData, sal_Int32 **pInternalCapacity)
Allows access to the internal data of this OStringBuffer, for effective manipulation.
Definition: strbuf.hxx:1074
sal_Int32 getLength() const
Returns the length (character count) of this string buffer.
Definition: strbuf.hxx:377
This String class provide base functionality for C++ like 8-Bit character array handling.
Definition: string.hxx:193
const char * getStr() const SAL_RETURNS_NONNULL
Returns a pointer to the characters of this string.
Definition: string.hxx:697
sal_Int32 getLength() const
Returns the length of this string.
Definition: string.hxx:671
A string buffer implements a mutable sequence of characters.
Definition: ustrbuf.hxx:73
sal_Int32 getLength() const
Returns the length (character count) of this string buffer.
Definition: ustrbuf.hxx:398
void accessInternals(rtl_uString ***pInternalData, sal_Int32 **pInternalCapacity)
Allows access to the internal data of this OUStringBuffer, for effective manipulation.
Definition: ustrbuf.hxx:1351
This String class provides base functionality for C++ like Unicode character array handling.
Definition: ustring.hxx:168
const sal_Unicode * getStr() const SAL_RETURNS_NONNULL
Returns a pointer to the Unicode character buffer for this string.
Definition: ustring.hxx:845
sal_Int32 getLength() const
Returns the length of this string.
Definition: ustring.hxx:823