1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: math.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #if !defined INCLUDED_RTL_MATH_HXX
32 #define INCLUDED_RTL_MATH_HXX
35 #include "rtl/string.hxx"
36 #include "rtl/ustring.hxx"
37 #include "rtl/ustrbuf.hxx"
38 #include "sal/mathconf.h"
39 #include "sal/types.h"
47 /** A wrapper around rtl_math_doubleToString.
49 inline rtl::OString
doubleToString(double fValue
, rtl_math_StringFormat eFormat
,
51 sal_Char cDecSeparator
,
52 sal_Int32
const * pGroups
,
53 sal_Char cGroupSeparator
,
54 bool bEraseTrailingDecZeros
= false)
57 rtl_math_doubleToString(&aResult
.pData
, 0, 0, fValue
, eFormat
, nDecPlaces
,
58 cDecSeparator
, pGroups
, cGroupSeparator
,
59 bEraseTrailingDecZeros
);
63 /** A wrapper around rtl_math_doubleToString, with no grouping.
65 inline rtl::OString
doubleToString(double fValue
, rtl_math_StringFormat eFormat
,
67 sal_Char cDecSeparator
,
68 bool bEraseTrailingDecZeros
= false)
71 rtl_math_doubleToString(&aResult
.pData
, 0, 0, fValue
, eFormat
, nDecPlaces
,
72 cDecSeparator
, 0, 0, bEraseTrailingDecZeros
);
76 /** A wrapper around rtl_math_doubleToUString.
78 inline rtl::OUString
doubleToUString(double fValue
,
79 rtl_math_StringFormat eFormat
,
81 sal_Unicode cDecSeparator
,
82 sal_Int32
const * pGroups
,
83 sal_Unicode cGroupSeparator
,
84 bool bEraseTrailingDecZeros
= false)
86 rtl::OUString aResult
;
87 rtl_math_doubleToUString(&aResult
.pData
, 0, 0, fValue
, eFormat
, nDecPlaces
,
88 cDecSeparator
, pGroups
, cGroupSeparator
,
89 bEraseTrailingDecZeros
);
93 /** A wrapper around rtl_math_doubleToUString, with no grouping.
95 inline rtl::OUString
doubleToUString(double fValue
,
96 rtl_math_StringFormat eFormat
,
98 sal_Unicode cDecSeparator
,
99 bool bEraseTrailingDecZeros
= false)
101 rtl::OUString aResult
;
102 rtl_math_doubleToUString(&aResult
.pData
, 0, 0, fValue
, eFormat
, nDecPlaces
,
103 cDecSeparator
, 0, 0, bEraseTrailingDecZeros
);
107 /** A wrapper around rtl_math_doubleToUString that appends to an
110 inline void doubleToUStringBuffer( rtl::OUStringBuffer
& rBuffer
, double fValue
,
111 rtl_math_StringFormat eFormat
,
112 sal_Int32 nDecPlaces
,
113 sal_Unicode cDecSeparator
,
114 sal_Int32
const * pGroups
,
115 sal_Unicode cGroupSeparator
,
116 bool bEraseTrailingDecZeros
= false)
118 rtl_uString
** pData
;
119 sal_Int32
* pCapacity
;
120 rBuffer
.accessInternals( &pData
, &pCapacity
);
121 rtl_math_doubleToUString( pData
, pCapacity
, rBuffer
.getLength(), fValue
,
122 eFormat
, nDecPlaces
, cDecSeparator
, pGroups
,
123 cGroupSeparator
, bEraseTrailingDecZeros
);
126 /** A wrapper around rtl_math_doubleToUString that appends to an
127 rtl::OUStringBuffer, with no grouping.
129 inline void doubleToUStringBuffer( rtl::OUStringBuffer
& rBuffer
, double fValue
,
130 rtl_math_StringFormat eFormat
,
131 sal_Int32 nDecPlaces
,
132 sal_Unicode cDecSeparator
,
133 bool bEraseTrailingDecZeros
= false)
135 rtl_uString
** pData
;
136 sal_Int32
* pCapacity
;
137 rBuffer
.accessInternals( &pData
, &pCapacity
);
138 rtl_math_doubleToUString( pData
, pCapacity
, rBuffer
.getLength(), fValue
,
139 eFormat
, nDecPlaces
, cDecSeparator
, 0, 0,
140 bEraseTrailingDecZeros
);
143 /** A wrapper around rtl_math_stringToDouble.
145 inline double stringToDouble(rtl::OString
const & rString
,
146 sal_Char cDecSeparator
, sal_Char cGroupSeparator
,
147 rtl_math_ConversionStatus
* pStatus
,
148 sal_Int32
* pParsedEnd
)
150 sal_Char
const * pBegin
= rString
.getStr();
151 sal_Char
const * pEnd
;
152 double fResult
= rtl_math_stringToDouble(pBegin
,
153 pBegin
+ rString
.getLength(),
154 cDecSeparator
, cGroupSeparator
,
157 *pParsedEnd
= (sal_Int32
)(pEnd
- pBegin
);
161 /** A wrapper around rtl_math_uStringToDouble.
163 inline double stringToDouble(rtl::OUString
const & rString
,
164 sal_Unicode cDecSeparator
,
165 sal_Unicode cGroupSeparator
,
166 rtl_math_ConversionStatus
* pStatus
,
167 sal_Int32
* pParsedEnd
)
169 sal_Unicode
const * pBegin
= rString
.getStr();
170 sal_Unicode
const * pEnd
;
171 double fResult
= rtl_math_uStringToDouble(pBegin
,
172 pBegin
+ rString
.getLength(),
173 cDecSeparator
, cGroupSeparator
,
176 *pParsedEnd
= (sal_Int32
)(pEnd
- pBegin
);
180 /** A wrapper around rtl_math_round.
183 double fValue
, int nDecPlaces
= 0,
184 rtl_math_RoundingMode eMode
= rtl_math_RoundingMode_Corrected
)
186 return rtl_math_round(fValue
, nDecPlaces
, eMode
);
189 /** A wrapper around rtl_math_pow10Exp.
191 inline double pow10Exp(double fValue
, int nExp
)
193 return rtl_math_pow10Exp(fValue
, nExp
);
196 /** A wrapper around rtl_math_approxValue.
198 inline double approxValue(double fValue
)
200 return rtl_math_approxValue(fValue
);
203 /** A wrapper around rtl_math_expm1.
205 inline double expm1(double fValue
)
207 return rtl_math_expm1(fValue
);
210 /** A wrapper around rtl_math_log1p.
212 inline double log1p(double fValue
)
214 return rtl_math_log1p(fValue
);
217 /** A wrapper around rtl_math_atanh.
219 inline double atanh(double fValue
)
221 return rtl_math_atanh(fValue
);
224 /** A wrapper around rtl_math_erf.
226 inline double erf(double fValue
)
228 return rtl_math_erf(fValue
);
231 /** A wrapper around rtl_math_erfc.
233 inline double erfc(double fValue
)
235 return rtl_math_erfc(fValue
);
238 /** A wrapper around rtl_math_asinh.
240 inline double asinh(double fValue
)
242 return rtl_math_asinh(fValue
);
245 /** A wrapper around rtl_math_acosh.
247 inline double acosh(double fValue
)
249 return rtl_math_acosh(fValue
);
253 /** Test equality of two values with an accuracy of the magnitude of the
254 given values scaled by 2^-48 (4 bits roundoff stripped).
257 approxEqual( value!=0.0, 0.0 ) _never_ yields true.
259 inline bool approxEqual(double a
, double b
)
264 return (x
< 0.0 ? -x
: x
)
265 < ((a
< 0.0 ? -a
: a
) * (1.0 / (16777216.0 * 16777216.0)));
270 If signs differ and the absolute values are equal according to approxEqual()
271 the method returns 0.0 instead of calculating the sum.
273 If you wanted to sum up multiple values it would be convenient not to call
274 approxAdd() for each value but instead remember the first value not equal to
275 0.0, add all other values using normal + operator, and with the result and
276 the remembered value call approxAdd().
278 inline double approxAdd(double a
, double b
)
280 if ( ((a
< 0.0 && b
> 0.0) || (b
< 0.0 && a
> 0.0))
281 && approxEqual( a
, -b
) )
286 /** Substract two values (a-b).
288 If signs are identical and the values are equal according to approxEqual()
289 the method returns 0.0 instead of calculating the substraction.
291 inline double approxSub(double a
, double b
)
293 if ( ((a
< 0.0 && b
< 0.0) || (a
> 0.0 && b
> 0.0)) && approxEqual( a
, b
) )
298 /** floor() method taking approxValue() into account.
300 Use for expected integer values being calculated by double functions.
302 inline double approxFloor(double a
)
304 return floor( approxValue( a
));
307 /** ceil() method taking approxValue() into account.
309 Use for expected integer values being calculated by double functions.
311 inline double approxCeil(double a
)
313 return ceil( approxValue( a
));
316 /** Tests whether a value is neither INF nor NAN.
318 inline bool isFinite(double d
)
320 return SAL_MATH_FINITE(d
) != 0;
323 /** If a value represents +INF or -INF.
325 The sign bit may be queried with isSignBitSet().
327 If isFinite(d)==false and isInf(d)==false then NAN.
329 inline bool isInf(double d
)
331 // exponent==0x7ff fraction==0
332 return (SAL_MATH_FINITE(d
) == 0) &&
333 (reinterpret_cast< sal_math_Double
* >(&d
)->inf_parts
.fraction_hi
== 0)
334 && (reinterpret_cast< sal_math_Double
* >(&d
)->inf_parts
.fraction_lo
338 /** Test on any QNAN or SNAN.
340 inline bool isNan(double d
)
342 // exponent==0x7ff fraction!=0
343 return (SAL_MATH_FINITE(d
) == 0) && (
344 (reinterpret_cast< sal_math_Double
* >(&d
)->inf_parts
.fraction_hi
!= 0)
345 || (reinterpret_cast< sal_math_Double
* >(&d
)->inf_parts
.fraction_lo
349 /** If the sign bit is set.
351 inline bool isSignBitSet(double d
)
353 return reinterpret_cast< sal_math_Double
* >(&d
)->inf_parts
.sign
!= 0;
356 /** Set to +INF if bNegative==false or -INF if bNegative==true.
358 inline void setInf(double * pd
, bool bNegative
)
360 reinterpret_cast< sal_math_Double
* >(pd
)->w32_parts
.msw
361 = bNegative
? 0xFFF00000 : 0x7FF00000;
362 reinterpret_cast< sal_math_Double
* >(pd
)->w32_parts
.lsw
= 0;
367 inline void setNan(double * pd
)
369 reinterpret_cast< sal_math_Double
* >(pd
)->w32_parts
.msw
= 0x7FFFFFFF;
370 reinterpret_cast< sal_math_Double
* >(pd
)->w32_parts
.lsw
= 0xFFFFFFFF;
373 /** If a value is a valid argument for sin(), cos(), tan().
375 IEEE 754 specifies that absolute values up to 2^64 (=1.844e19) for the
376 radian must be supported by trigonometric functions. Unfortunately, at
377 least on x86 architectures, the FPU doesn't generate an error pattern for
378 values >2^64 but produces erroneous results instead and sets only the
379 "invalid operation" (IM) flag in the status word :-( Thus the application
380 has to handle it itself.
382 inline bool isValidArcArg(double d
)
385 <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
386 * static_cast< double >(static_cast< unsigned long >(0x80000000))
390 /** Safe sin(), returns NAN if not valid.
392 inline double sin(double d
)
394 if ( isValidArcArg( d
) )
400 /** Safe cos(), returns NAN if not valid.
402 inline double cos(double d
)
404 if ( isValidArcArg( d
) )
410 /** Safe tan(), returns NAN if not valid.
412 inline double tan(double d
)
414 if ( isValidArcArg( d
) )
424 #endif // INCLUDED_RTL_MATH_HXX