LibreOffice Module sc (master) 1
op_math_helpers.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
10#pragma once
11
12const char Math_IntgDecl[] ="double Intg(double n);\n";
13const char Math_Intg[] =
14"double Intg(double n)\n"
15"{\n"
16" if(trunc(n)==n )\n"
17" return n;\n"
18" else if(n<0)\n"
19" return trunc(n)-1;\n"
20" else\n"
21" return trunc(n)+1;\n"
22"}\n";
23
24const char nCorrValDecl[] ="double constant nCorrVal[]"
25"= {0, 9e-1, 9e-2, 9e-3, 9e-4, 9e-5, 9e-6, 9e-7, "
26"9e-8,9e-9, 9e-10, 9e-11, 9e-12, 9e-13, 9e-14, 9e-15};\n";
27
28const char RoundDecl[] = "double Round(double fValue);\n";
29
30const char Round[] =
31"double Round(double fValue)\n"
32"{\n"
33" if ( fValue == 0.0 )\n"
34" return fValue;\n"
35"\n"
36" double fFac = 0;\n"
37" int nExp;\n"
38" if ( fValue > 0.0 )\n"
39" nExp = ( floor( log10( fValue ) ) );\n"
40" else\n"
41" nExp = 0;\n"
42" int nIndex = 15 - nExp;\n"
43" if ( nIndex > 15 )\n"
44" nIndex = 15;\n"
45" else if ( nIndex <= 1 )\n"
46" nIndex = 0;\n"
47" fValue = floor( fValue + 0.5 + nCorrVal[nIndex] );\n"
48" return fValue;\n"
49"}\n";
50
51const char bikDecl[] = "double bik(double n,double k);\n";
52const char bik[] =
53"double bik(double n,double k)\n"
54"{\n"
55" double nVal1 = n;\n"
56" double nVal2 = k;\n"
57" n = n - 1;\n"
58" k = k - 1;\n"
59" while (k > 0)\n"
60" {\n"
61" nVal1 = nVal1 * n;\n"
62" nVal2 = nVal2 * k;\n"
63" k = k - 1;\n"
64" n = n - 1;\n"
65" }\n"
66" return (nVal1 / nVal2);\n"
67"}\n";
68
69const char local_cothDecl[] = "double local_coth(double n);\n";
70const char local_coth[] =
71"double local_coth(double n)\n"
72"{\n"
73" double a = exp(n);\n"
74" double b = exp(-n);\n"
75" double nVal = (a + b) / (a - b);\n"
76" return nVal;\n"
77"}\n";
78
79const char local_coshDecl[] = "double local_cosh(double n);\n";
80const char local_cosh[] =
81"double local_cosh(double n)\n"
82"{\n"
83" double nVal = (exp(n) + exp(-n)) / 2;\n"
84" return nVal;\n"
85"}\n";
86const char atan2Decl[] = "double arctan2(double y, double x);\n";
87const char atan2Content[] =
88"double arctan2(double y, double x)\n"
89"{\n"
90" if(y==0.0)\n"
91" return x >= 0 ? 0.0 : M_PI;\n"
92" double a,num,den,tmpPi;\n"
93" int flag;\n"
94" tmpPi = 0;\n"
95" if (fabs(x) >= fabs(y))\n"
96" {\n"
97" num = y;\n"
98" den = x;\n"
99" flag = 1;\n"
100" if (x < 0.0)\n"
101" tmpPi = M_PI;\n"
102" }\n"
103" if(fabs(x) < fabs(y))\n"
104" {\n"
105" num = x;\n"
106" den = y;\n"
107" flag = -1;\n"
108" tmpPi = M_PI_2;\n"
109" }\n"
110" a = atan(num/den);\n"
111" a = flag==1?a:-a;\n"
112" a = a + (y >= 0.0 ? tmpPi : -tmpPi);\n"
113" return a;\n"
114"}\n";
115
116const char is_representable_integerDecl[] = "int is_representable_integer(double a);\n";
118"int is_representable_integer(double a) {\n"
119" long kMaxInt = (1L << 53) - 1;\n"
120" if (a <= (double)kMaxInt)\n"
121" {\n"
122" long nInt = (long)a;\n"
123" double fInt;\n"
124" return (nInt <= kMaxInt &&\n"
125" (!((fInt = (double)nInt) < a) && !(fInt > a)));\n"
126" }\n"
127" return 0;\n"
128"}\n";
129
130const char approx_equalDecl[] = "int approx_equal(double a, double b);\n";
131const char approx_equal[] =
132"int approx_equal(double a, double b) {\n"
133" double e48 = 1.0 / (16777216.0 * 16777216.0);\n"
134" double e44 = e48 * 16.0;\n"
135" if (a == b)\n"
136" return 1;\n"
137" if (a == 0.0 || b == 0.0)\n"
138" return 0;\n"
139" double d = fabs(a - b);\n"
140" if (!isfinite(d))\n"
141" return 0; // Nan or Inf involved\n"
142" if (d > ((a = fabs(a)) * e44) || d > ((b = fabs(b)) * e44))\n"
143" return 0;\n"
144" if (is_representable_integer(d) && is_representable_integer(a) && is_representable_integer(b))\n"
145" return 0; // special case for representable integers.\n"
146" return (d < a * e48 && d < b * e48);\n"
147"}\n";
148
149const char fsum_approxDecl[] = "double fsum_approx(double a, double b);\n";
150const char fsum_approx[] =
151"double fsum_approx(double a, double b) {\n"
152" if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))\n"
153" && approx_equal( a, -b ) )\n"
154" return 0.0;\n"
155" return a + b;\n"
156"}\n";
157
158const char fsub_approxDecl[] = "double fsub_approx(double a, double b);\n";
159const char fsub_approx[] =
160"double fsub_approx(double a, double b) {\n"
161" if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approx_equal( a, b ) )\n"
162" return 0.0;\n"
163" return a - b;\n"
164"}\n";
165
166const char value_approxDecl[] = "double value_approx( double fValue );\n";
167const char value_approx[] =
168"double value_approx( double fValue )\n"
169"{\n"
170" const double fBigInt = 2199023255552.0;\n"
171" if (fValue == 0.0 || fValue == HUGE_VAL || !isfinite(fValue))\n"
172" return fValue;\n"
173" double fOrigValue = fValue;\n"
174" fValue = fabs(fValue);\n"
175" if (fValue > fBigInt)\n"
176" return fOrigValue;\n"
177" if (is_representable_integer(fValue))\n" // TODO? || getBitsInFracPart(fValue) <= 11)\n"
178" return fOrigValue;\n"
179" int nExp = (int)(floor(log10(fValue)));\n"
180" nExp = 14 - nExp;\n"
181" double fExpValue = pow(10.0,nExp);\n"
182" fValue *= fExpValue;\n"
183" if (!isfinite(fValue))\n"
184" return fOrigValue;\n"
185" fValue = round(fValue);\n"
186" fValue /= fExpValue;\n"
187" if (!isfinite(fValue))\n"
188" return fOrigValue;\n"
189" return copysign(fValue, fOrigValue);\n"
190"}\n";
191
192// This compares two cell contents, including possible string equalities (based on string ids
193// coming from DynamicKernelArgument::GetStringId()).
194// The EmptyIsZero conversion must not be have been done for the arguments.
195const char cell_equalDecl[] = "bool cell_equal(double a, double b, bool a_is_string, bool b_is_string);\n";
196const char cell_equal[] =
197"bool cell_equal(double a, double b, bool a_is_string, bool b_is_string) {\n"
198" if( !a_is_string && !b_is_string )\n"
199" return approx_equal( isnan(a) ? 0 : a, isnan(b) ? 0 : b );\n"
200" if( a_is_string && b_is_string )\n"
201" return a == b;\n"
202// empty strings and empty cells compare equal
203" if(( a_is_string && a == 0 && isnan(b)) || ( b_is_string && b == 0 && isnan(a)))\n"
204" return true;\n"
205" return false;\n"
206"}\n";
207
208/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char fsum_approxDecl[]
const char local_cothDecl[]
const char is_representable_integerDecl[]
const char fsum_approx[]
const char atan2Decl[]
const char atan2Content[]
const char Round[]
const char Math_Intg[]
const char fsub_approx[]
const char fsub_approxDecl[]
const char local_cosh[]
const char bikDecl[]
const char RoundDecl[]
const char approx_equalDecl[]
const char approx_equal[]
const char local_coshDecl[]
const char local_coth[]
const char value_approxDecl[]
const char value_approx[]
const char cell_equal[]
const char Math_IntgDecl[]
const char nCorrValDecl[]
const char cell_equalDecl[]
const char is_representable_integer[]
const char bik[]