xref: /trunk/main/sal/inc/rtl/math.h (revision cda7f8b3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #if !defined INCLUDED_RTL_MATH_H
25 #define INCLUDED_RTL_MATH_H
26 
27 #include "rtl/ustring.h"
28 #include "sal/types.h"
29 
30 #if defined __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33 
34 /** Formatting modes for rtl_math_doubleToString and rtl_math_doubleToUString
35     and rtl_math_doubleToUStringBuffer.
36  */
37 enum rtl_math_StringFormat
38 {
39     /** Like sprintf() %E.
40      */
41     rtl_math_StringFormat_E,
42 
43     /** Like sprintf() %f.
44      */
45     rtl_math_StringFormat_F,
46 
47     /** Like sprintf() %G, 'F' or 'E' format is used depending on which one is
48         more compact.
49     */
50     rtl_math_StringFormat_G,
51 
52     /** Automatic, 'F' or 'E' format is used depending on the numeric value to
53         be formatted.
54      */
55     rtl_math_StringFormat_Automatic,
56 
57     /** @internal
58      */
59     rtl_math_StringFormat_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
60 };
61 
62 /** Status for rtl_math_stringToDouble and rtl_math_uStringToDouble.
63  */
64 enum rtl_math_ConversionStatus
65 {
66     /** Conversion was successful.
67      */
68     rtl_math_ConversionStatus_Ok,
69 
70     /** Conversion caused overflow or underflow.
71      */
72     rtl_math_ConversionStatus_OutOfRange,
73 
74     /** @internal
75      */
76     rtl_math_ConversionStatus_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
77 };
78 
79 /** Rounding modes for rtl_math_round.
80  */
81 enum rtl_math_RoundingMode
82 {
83     /** Like HalfUp, but corrects roundoff errors, preferred.
84      */
85     rtl_math_RoundingMode_Corrected,
86 
87     /** Floor of absolute value, signed return (commercial).
88      */
89     rtl_math_RoundingMode_Down,
90 
91     /** Ceil of absolute value, signed return (commercial).
92      */
93     rtl_math_RoundingMode_Up,
94 
95     /** Floor of signed value.
96      */
97     rtl_math_RoundingMode_Floor,
98 
99     /** Ceil of signed value.
100      */
101     rtl_math_RoundingMode_Ceiling,
102 
103     /** Frac <= 0.5 ? floor of abs : ceil of abs, signed return.
104      */
105     rtl_math_RoundingMode_HalfDown,
106 
107     /** Frac < 0.5 ? floor of abs : ceil of abs, signed return (mathematical).
108      */
109     rtl_math_RoundingMode_HalfUp,
110 
111     /** IEEE rounding mode (statistical).
112      */
113     rtl_math_RoundingMode_HalfEven,
114 
115     /** @internal
116      */
117     rtl_math_RoundingMode_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
118 };
119 
120 /** Special decimal places constants for rtl_math_doubleToString and
121     rtl_math_doubleToUString and rtl_math_doubleToUStringBuffer.
122  */
123 enum rtl_math_DecimalPlaces
124 {
125     /** Value to be used with rtl_math_StringFormat_Automatic.
126      */
127     rtl_math_DecimalPlaces_Max = 0x7ffffff,
128 
129     /** Value to be used with rtl_math_StringFormat_G.
130         In fact the same value as rtl_math_DecimalPlaces_Max, just an alias for
131         better understanding.
132      */
133     rtl_math_DecimalPlaces_DefaultSignificance = 0x7ffffff
134 };
135 
136 
137 /** Conversions analogous to sprintf() using internal rounding.
138 
139     +/-HUGE_VAL are converted to "INF" and "-INF", NAN values are
140     converted to "NaN".
141 
142     @param pResult
143     Returns the resulting byte string.  Must itself not be null, and must point
144     to either null or a valid string.
145 
146     @param pResultCapacity
147     If null, pResult is considered to point to immutable strings, and a new
148     string will be allocated in pResult.
149     If non-null, it points to the current capacity of pResult, which is
150     considered to point to a string buffer (pResult must not itself be null in
151     this case, and must point to a string that has room for the given capacity).
152     The string representation of the given double value is inserted into pResult
153     at position nResultOffset.  If pResult's current capacity is too small, a
154     new string buffer will be allocated in pResult as necessary, and
155     pResultCapacity will contain the new capacity on return.
156 
157     @param nResultOffset
158     If pResult is used as a string buffer (i.e., pResultCapacity is non-null),
159     nResultOffset specifies the insertion offset within the buffer.  Ignored
160     otherwise.
161 
162     @param fValue
163     The value to convert.
164 
165     @param eFormat
166     The format to use, one of rtl_math_StringFormat.
167 
168     @param nDecPlaces
169     The number of decimals to be generated.  Effectively fValue is rounded at
170     this position, specifying nDecPlaces <= 0 accordingly rounds the value
171     before the decimal point and fills with zeros.
172     If eFormat == rtl_math_StringFormat_Automatic and nDecPlaces ==
173     rtl_math_DecimalPlaces_Max, the highest number of significant decimals
174     possible is generated.
175     If eFormat == rtl_math_StringFormat_G, nDecPlaces specifies the number of
176     significant digits instead.  If nDecPlaces ==
177     rtl_math_DecimalPlaces_DefaultSignificance, the default number (currently 6
178     as implemented by most libraries) of significant digits is generated.
179     According to the ANSI C90 standard the E style will be used only if the
180     exponent resulting from the conversion is less than -4 or greater than or
181     equal to the precision.  However, as opposed to the ANSI standard, trailing
182     zeros are not necessarily removed from the fractional portion of the result
183     unless bEraseTrailingDecZeros == true was specified.
184 
185     @param cDecSeparator
186     The decimal separator.
187 
188     @param pGroups
189     Either null (no grouping is used), or a null-terminated list of group
190     lengths.  Each group length must be strictly positive.  If the number of
191     digits in a conversion exceeds the specified range, the last (highest) group
192     length is repeated as needed.  Values are applied from right to left, for a
193     grouping of 1,00,00,000 you'd have to specify pGroups={3,2,0}.
194 
195     @param cGroupSeparator
196     The group separator.  Ignored if pGroups is null.
197 
198     @param bEraseTrailingDecZeros
199     Trailing zeros in decimal places are erased.
200  */
201 void SAL_CALL rtl_math_doubleToString(rtl_String ** pResult,
202                                       sal_Int32 * pResultCapacity,
203                                       sal_Int32 nResultOffset, double fValue,
204                                       enum rtl_math_StringFormat eFormat,
205                                       sal_Int32 nDecPlaces,
206                                       sal_Char cDecSeparator,
207                                       sal_Int32 const * pGroups,
208                                       sal_Char cGroupSeparator,
209                                       sal_Bool bEraseTrailingDecZeros)
210     SAL_THROW_EXTERN_C();
211 
212 /** Conversions analogous to sprintf() using internal rounding.
213 
214     +/-HUGE_VAL are converted to "INF" and "-INF", NAN values are
215     converted to "NaN".
216 
217     @param pResult
218     Returns the resulting Unicode string.  Must itself not be null, and must
219     point to either null or a valid string.
220 
221     @param pResultCapacity
222     If null, pResult is considered to point to immutable strings, and a new
223     string will be allocated in pResult.
224     If non-null, it points to the current capacity of pResult, which is
225     considered to point to a string buffer (pResult must not itself be null in
226     this case, and must point to a string that has room for the given capacity).
227     The string representation of the given double value is inserted into pResult
228     at position nResultOffset.  If pResult's current capacity is too small, a
229     new string buffer will be allocated in pResult as necessary, and
230     pResultCapacity will contain the new capacity on return.
231 
232     @param nResultOffset
233     If pResult is used as a string buffer (i.e., pResultCapacity is non-null),
234     nResultOffset specifies the insertion offset within the buffer.  Ignored
235     otherwise.
236 
237     @param fValue
238     The value to convert.
239 
240     @param eFormat
241     The format to use, one of rtl_math_StringFormat.
242 
243     @param nDecPlaces
244     The number of decimals to be generated.  Effectively fValue is rounded at
245     this position, specifying nDecPlaces <= 0 accordingly rounds the value
246     before the decimal point and fills with zeros.
247     If eFormat == rtl_math_StringFormat_Automatic and nDecPlaces ==
248     rtl_math_DecimalPlaces_Max, the highest number of significant decimals
249     possible is generated.
250     If eFormat == rtl_math_StringFormat_G, nDecPlaces specifies the number of
251     significant digits instead.  If nDecPlaces ==
252     rtl_math_DecimalPlaces_DefaultSignificance, the default number (currently 6
253     as implemented by most libraries) of significant digits is generated.
254     According to the ANSI C90 standard the E style will be used only if the
255     exponent resulting from the conversion is less than -4 or greater than or
256     equal to the precision.  However, as opposed to the ANSI standard, trailing
257     zeros are not necessarily removed from the fractional portion of the result
258     unless bEraseTrailingDecZeros == true was specified.
259 
260     @param cDecSeparator
261     The decimal separator.
262 
263     @param pGroups
264     Either null (no grouping is used), or a null-terminated list of group
265     lengths.  Each group length must be strictly positive.  If the number of
266     digits in a conversion exceeds the specified range, the last (highest) group
267     length is repeated as needed.  Values are applied from right to left, for a
268     grouping of 1,00,00,000 you'd have to specify pGroups={3,2,0}.
269 
270     @param cGroupSeparator
271     The group separator.  Ignored if pGroups is null.
272 
273     @param bEraseTrailingDecZeros
274     Trailing zeros in decimal places are erased.
275  */
276 void SAL_CALL rtl_math_doubleToUString(rtl_uString ** pResult,
277                                        sal_Int32 * pResultCapacity,
278                                        sal_Int32 nResultOffset, double fValue,
279                                        enum rtl_math_StringFormat eFormat,
280                                        sal_Int32 nDecPlaces,
281                                        sal_Unicode cDecSeparator,
282                                        sal_Int32 const * pGroups,
283                                        sal_Unicode cGroupSeparator,
284                                        sal_Bool bEraseTrailingDecZeros)
285     SAL_THROW_EXTERN_C();
286 
287 /** Conversion analogous to strtod(), convert a string representing a
288     decimal number into a double value.
289 
290     Leading tabs (0x09) and spaces (0x20) are eaten.  Overflow returns
291     +/-HUGE_VAL, underflow 0.  In both cases pStatus is set to
292     rtl_math_ConversionStatus_OutOfRange, otherwise to
293     rtl_math_ConversionStatus_Ok.  "INF", "-INF" and "+/-1.#INF" are
294     recognized as +/-HUGE_VAL, pStatus is set to
295     rtl_math_ConversionStatus_OutOfRange.  "NaN" and "+/-1.#NAN" are
296     recognized and the value is set to +/-NAN, pStatus is set to
297     rtl_math_ConversionStatus_Ok.
298 
299     @param pBegin
300     Points to the start of the byte string to convert.  Must not be null.
301 
302     @param pEnd
303     Points one past the end of the byte string to convert.  The condition
304     pEnd >= pBegin must hold.
305 
306     @param cDecSeparator
307     The decimal separator.
308 
309     @param cGroupSeparator
310     The group (aka thousands) separator.
311 
312     @param pStatus
313     If non-null, returns the status of the conversion.
314 
315     @param pParsedEnd
316     If non-null, returns one past the position of the last character parsed
317     away.  Thus if [pBegin..pEnd) only contains the numerical string to be
318     parsed, *pParsedEnd == pEnd on return.  If no numerical (sub-)string is
319     found, *pParsedEnd == pBegin on return, even if there was leading
320     whitespace.
321  */
322 double SAL_CALL rtl_math_stringToDouble(
323     sal_Char const * pBegin, sal_Char const * pEnd, sal_Char cDecSeparator,
324     sal_Char cGroupSeparator, enum rtl_math_ConversionStatus * pStatus,
325     sal_Char const ** pParsedEnd) SAL_THROW_EXTERN_C();
326 
327 /** Conversion analogous to strtod(), convert a string representing a
328     decimal number into a double value.
329 
330     Leading tabs (U+0009) and spaces (U+0020) are eaten.  Overflow returns
331     +/-HUGE_VAL, underflow 0.  In both cases pStatus is set to
332     rtl_math_ConversionStatus_OutOfRange, otherwise to
333     rtl_math_ConversionStatus_Ok.  "INF", "-INF" and "+/-1.#INF" are
334     recognized as +/-HUGE_VAL, pStatus is set to
335     rtl_math_ConversionStatus_OutOfRange.  "NaN" and "+/-1.#NAN" are
336     recognized and the value is set to +/-NAN, pStatus is set to
337     rtl_math_ConversionStatus_Ok.
338 
339     @param pBegin
340     Points to the start of the Unicode string to convert.  Must not be null.
341 
342     @param pEnd
343     Points one past the end of the Unicode string to convert.  The condition
344     pEnd >= pBegin must hold.
345 
346     @param cDecSeparator
347     The decimal separator.
348 
349     @param cGroupSeparator
350     The group (aka thousands) separator.
351 
352     @param pStatus
353     If non-null, returns the status of the conversion.
354 
355     @param pParsedEnd
356     If non-null, returns one past the position of the last character parsed
357     away.  Thus if [pBegin..pEnd) only contains the numerical string to be
358     parsed, *pParsedEnd == pEnd on return.  If no numerical (sub-)string is
359     found, *pParsedEnd == pBegin on return, even if there was leading
360     whitespace.
361  */
362 double SAL_CALL rtl_math_uStringToDouble(
363     sal_Unicode const * pBegin, sal_Unicode const * pEnd,
364     sal_Unicode cDecSeparator, sal_Unicode cGroupSeparator,
365     enum rtl_math_ConversionStatus * pStatus, sal_Unicode const ** pParsedEnd)
366     SAL_THROW_EXTERN_C();
367 
368 /** Rounds a double value.
369 
370     @param fValue
371     Specifies the value to be rounded.
372 
373     @param nDecPlaces
374     Specifies the decimal place where rounding occurs.  Must be in the range
375     -20 to +20, inclusive.  Negative if rounding occurs before the decimal
376     point.
377 
378     @param eMode
379     Specifies the rounding mode.
380  */
381 double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
382                                enum rtl_math_RoundingMode eMode)
383     SAL_THROW_EXTERN_C();
384 
385 /** Scales fVal to a power of 10 without calling pow() or div() for nExp values
386     between -16 and +16, providing a faster method.
387 
388     @param fValue
389     The value to be raised.
390 
391     @param nExp
392     The exponent.
393 
394     @return
395     fVal * pow(10.0, nExp)
396  */
397 double SAL_CALL rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C();
398 
399 /** Similar to pow() with stricter exception handling for indeterminate values.
400 
401     powr is specified in the IEEE 754 - 2008 Floating Point Standard.
402 
403     @param fValue
404     The value to be raised.
405 
406     @param fExp
407     The exponent.
408 
409     @return
410     powr(fValue, fExp)
411  */
412 double SAL_CALL rtl_math_powr(double fValue, double fExp) SAL_THROW_EXTERN_C();
413 
414 /** Rounds value to 15 significant decimal digits.
415 
416     @param fValue
417     The value to be rounded.
418   */
419 double SAL_CALL rtl_math_approxValue(double fValue) SAL_THROW_EXTERN_C();
420 
421 /** Returns more accurate e^x-1 for x near 0 than calculating directly.
422 
423     expm1 is part of the C99 standard, but not provided by some compilers.
424 
425     @param fValue
426     The value x in the term e^x-1.
427   */
428 double SAL_CALL rtl_math_expm1(double fValue) SAL_THROW_EXTERN_C();
429 
430 /** Returns more accurate log(1+x) for x near 0 than calculating directly.
431 
432     log1p is part of the C99 standard, but not provided by some compilers.
433 
434     @param fValue
435     The value x in the term log(1+x).
436   */
437 double SAL_CALL rtl_math_log1p(double fValue) SAL_THROW_EXTERN_C();
438 
439 /** Returns more accurate atanh(x) for x near 0 than calculating
440     0.5*log((1+x)/(1-x)).
441 
442     atanh is part of the C99 standard, but not provided by some compilers.
443 
444     @param fValue
445     The value x in the term atanh(x).
446   */
447 double SAL_CALL rtl_math_atanh(double fValue) SAL_THROW_EXTERN_C();
448 
449 /** Returns values of the Errorfunction erf.
450 
451     erf is part of the C99 standard, but not provided by some compilers.
452 
453     @param fValue
454     The value x in the term erf(x).
455   */
456 double SAL_CALL rtl_math_erf(double fValue) SAL_THROW_EXTERN_C();
457 
458 /** Returns values of the complement Errorfunction erfc.
459 
460     erfc is part of the C99 standard, but not provided by some compilers.
461 
462     @param fValue
463     The value x in the term erfc(x).
464   */
465 double SAL_CALL rtl_math_erfc(double fValue) SAL_THROW_EXTERN_C();
466 
467 /** Returns values of the inverse hyperbolic sine.
468 
469     asinh is part of the C99 standard, but not provided by some compilers.
470 
471     @param fValue
472     The value x in the term asinh(x).
473   */
474 double SAL_CALL rtl_math_asinh(double fValue) SAL_THROW_EXTERN_C();
475 
476 /** Returns values of the inverse hyperbolic cosine.
477 
478     acosh is part of the C99 standard, but not provided by some compilers.
479 
480     @param fValue
481     The value x in the term acosh(x).
482   */
483 double SAL_CALL rtl_math_acosh(double fValue) SAL_THROW_EXTERN_C();
484 
485 #if defined __cplusplus
486 }
487 #endif /* __cplusplus */
488 
489 #endif /* INCLUDED_RTL_MATH_H */
490