PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.3
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.3
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / phpoffice / phpexcel / Classes / PHPExcel / Calculation / Engineering.php

Engineering.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.0.3, at vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Engineering.php

2,506 lines 96.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * PHPExcel
4 *
5 * Copyright (c) 2006 - 2014 PHPExcel
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 * @category PHPExcel
22 * @package PHPExcel_Calculation
23 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25 * @version ##VERSION##, ##DATE##
26 */
27
28
29 /** PHPExcel root directory */
30 if (!defined('PHPEXCEL_ROOT')) {
31 /**
32 * @ignore
33 */
34 define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
35 require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
36 }
37
38
39 /** EULER */
40 define('EULER', 2.71828182845904523536);
41
42
43 /**
44 * PHPExcel_Calculation_Engineering
45 *
46 * @category PHPExcel
47 * @package PHPExcel_Calculation
48 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
49 */
50 class PHPExcel_Calculation_Engineering {
51
52 /**
53 * Details of the Units of measure that can be used in CONVERTUOM()
54 *
55 * @var mixed[]
56 */
57 private static $_conversionUnits = array( 'g' => array( 'Group' => 'Mass', 'Unit Name' => 'Gram', 'AllowPrefix' => True ),
58 'sg' => array( 'Group' => 'Mass', 'Unit Name' => 'Slug', 'AllowPrefix' => False ),
59 'lbm' => array( 'Group' => 'Mass', 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => False ),
60 'u' => array( 'Group' => 'Mass', 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => True ),
61 'ozm' => array( 'Group' => 'Mass', 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => False ),
62 'm' => array( 'Group' => 'Distance', 'Unit Name' => 'Meter', 'AllowPrefix' => True ),
63 'mi' => array( 'Group' => 'Distance', 'Unit Name' => 'Statute mile', 'AllowPrefix' => False ),
64 'Nmi' => array( 'Group' => 'Distance', 'Unit Name' => 'Nautical mile', 'AllowPrefix' => False ),
65 'in' => array( 'Group' => 'Distance', 'Unit Name' => 'Inch', 'AllowPrefix' => False ),
66 'ft' => array( 'Group' => 'Distance', 'Unit Name' => 'Foot', 'AllowPrefix' => False ),
67 'yd' => array( 'Group' => 'Distance', 'Unit Name' => 'Yard', 'AllowPrefix' => False ),
68 'ang' => array( 'Group' => 'Distance', 'Unit Name' => 'Angstrom', 'AllowPrefix' => True ),
69 'Pica' => array( 'Group' => 'Distance', 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => False ),
70 'yr' => array( 'Group' => 'Time', 'Unit Name' => 'Year', 'AllowPrefix' => False ),
71 'day' => array( 'Group' => 'Time', 'Unit Name' => 'Day', 'AllowPrefix' => False ),
72 'hr' => array( 'Group' => 'Time', 'Unit Name' => 'Hour', 'AllowPrefix' => False ),
73 'mn' => array( 'Group' => 'Time', 'Unit Name' => 'Minute', 'AllowPrefix' => False ),
74 'sec' => array( 'Group' => 'Time', 'Unit Name' => 'Second', 'AllowPrefix' => True ),
75 'Pa' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ),
76 'p' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ),
77 'atm' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ),
78 'at' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ),
79 'mmHg' => array( 'Group' => 'Pressure', 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => True ),
80 'N' => array( 'Group' => 'Force', 'Unit Name' => 'Newton', 'AllowPrefix' => True ),
81 'dyn' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ),
82 'dy' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ),
83 'lbf' => array( 'Group' => 'Force', 'Unit Name' => 'Pound force', 'AllowPrefix' => False ),
84 'J' => array( 'Group' => 'Energy', 'Unit Name' => 'Joule', 'AllowPrefix' => True ),
85 'e' => array( 'Group' => 'Energy', 'Unit Name' => 'Erg', 'AllowPrefix' => True ),
86 'c' => array( 'Group' => 'Energy', 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => True ),
87 'cal' => array( 'Group' => 'Energy', 'Unit Name' => 'IT calorie', 'AllowPrefix' => True ),
88 'eV' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ),
89 'ev' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ),
90 'HPh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ),
91 'hh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ),
92 'Wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ),
93 'wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ),
94 'flb' => array( 'Group' => 'Energy', 'Unit Name' => 'Foot-pound', 'AllowPrefix' => False ),
95 'BTU' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ),
96 'btu' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ),
97 'HP' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ),
98 'h' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ),
99 'W' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ),
100 'w' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ),
101 'T' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Tesla', 'AllowPrefix' => True ),
102 'ga' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Gauss', 'AllowPrefix' => True ),
103 'C' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ),
104 'cel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ),
105 'F' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ),
106 'fah' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ),
107 'K' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ),
108 'kel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ),
109 'tsp' => array( 'Group' => 'Liquid', 'Unit Name' => 'Teaspoon', 'AllowPrefix' => False ),
110 'tbs' => array( 'Group' => 'Liquid', 'Unit Name' => 'Tablespoon', 'AllowPrefix' => False ),
111 'oz' => array( 'Group' => 'Liquid', 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => False ),
112 'cup' => array( 'Group' => 'Liquid', 'Unit Name' => 'Cup', 'AllowPrefix' => False ),
113 'pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ),
114 'us_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ),
115 'uk_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => False ),
116 'qt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Quart', 'AllowPrefix' => False ),
117 'gal' => array( 'Group' => 'Liquid', 'Unit Name' => 'Gallon', 'AllowPrefix' => False ),
118 'l' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True ),
119 'lt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True )
120 );
121
122 /**
123 * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM()
124 *
125 * @var mixed[]
126 */
127 private static $_conversionMultipliers = array( 'Y' => array( 'multiplier' => 1E24, 'name' => 'yotta' ),
128 'Z' => array( 'multiplier' => 1E21, 'name' => 'zetta' ),
129 'E' => array( 'multiplier' => 1E18, 'name' => 'exa' ),
130 'P' => array( 'multiplier' => 1E15, 'name' => 'peta' ),
131 'T' => array( 'multiplier' => 1E12, 'name' => 'tera' ),
132 'G' => array( 'multiplier' => 1E9, 'name' => 'giga' ),
133 'M' => array( 'multiplier' => 1E6, 'name' => 'mega' ),
134 'k' => array( 'multiplier' => 1E3, 'name' => 'kilo' ),
135 'h' => array( 'multiplier' => 1E2, 'name' => 'hecto' ),
136 'e' => array( 'multiplier' => 1E1, 'name' => 'deka' ),
137 'd' => array( 'multiplier' => 1E-1, 'name' => 'deci' ),
138 'c' => array( 'multiplier' => 1E-2, 'name' => 'centi' ),
139 'm' => array( 'multiplier' => 1E-3, 'name' => 'milli' ),
140 'u' => array( 'multiplier' => 1E-6, 'name' => 'micro' ),
141 'n' => array( 'multiplier' => 1E-9, 'name' => 'nano' ),
142 'p' => array( 'multiplier' => 1E-12, 'name' => 'pico' ),
143 'f' => array( 'multiplier' => 1E-15, 'name' => 'femto' ),
144 'a' => array( 'multiplier' => 1E-18, 'name' => 'atto' ),
145 'z' => array( 'multiplier' => 1E-21, 'name' => 'zepto' ),
146 'y' => array( 'multiplier' => 1E-24, 'name' => 'yocto' )
147 );
148
149 /**
150 * Details of the Units of measure conversion factors, organised by group
151 *
152 * @var mixed[]
153 */
154 private static $_unitConversions = array( 'Mass' => array( 'g' => array( 'g' => 1.0,
155 'sg' => 6.85220500053478E-05,
156 'lbm' => 2.20462291469134E-03,
157 'u' => 6.02217000000000E+23,
158 'ozm' => 3.52739718003627E-02
159 ),
160 'sg' => array( 'g' => 1.45938424189287E+04,
161 'sg' => 1.0,
162 'lbm' => 3.21739194101647E+01,
163 'u' => 8.78866000000000E+27,
164 'ozm' => 5.14782785944229E+02
165 ),
166 'lbm' => array( 'g' => 4.5359230974881148E+02,
167 'sg' => 3.10810749306493E-02,
168 'lbm' => 1.0,
169 'u' => 2.73161000000000E+26,
170 'ozm' => 1.60000023429410E+01
171 ),
172 'u' => array( 'g' => 1.66053100460465E-24,
173 'sg' => 1.13782988532950E-28,
174 'lbm' => 3.66084470330684E-27,
175 'u' => 1.0,
176 'ozm' => 5.85735238300524E-26
177 ),
178 'ozm' => array( 'g' => 2.83495152079732E+01,
179 'sg' => 1.94256689870811E-03,
180 'lbm' => 6.24999908478882E-02,
181 'u' => 1.70725600000000E+25,
182 'ozm' => 1.0
183 )
184 ),
185 'Distance' => array( 'm' => array( 'm' => 1.0,
186 'mi' => 6.21371192237334E-04,
187 'Nmi' => 5.39956803455724E-04,
188 'in' => 3.93700787401575E+01,
189 'ft' => 3.28083989501312E+00,
190 'yd' => 1.09361329797891E+00,
191 'ang' => 1.00000000000000E+10,
192 'Pica' => 2.83464566929116E+03
193 ),
194 'mi' => array( 'm' => 1.60934400000000E+03,
195 'mi' => 1.0,
196 'Nmi' => 8.68976241900648E-01,
197 'in' => 6.33600000000000E+04,
198 'ft' => 5.28000000000000E+03,
199 'yd' => 1.76000000000000E+03,
200 'ang' => 1.60934400000000E+13,
201 'Pica' => 4.56191999999971E+06
202 ),
203 'Nmi' => array( 'm' => 1.85200000000000E+03,
204 'mi' => 1.15077944802354E+00,
205 'Nmi' => 1.0,
206 'in' => 7.29133858267717E+04,
207 'ft' => 6.07611548556430E+03,
208 'yd' => 2.02537182785694E+03,
209 'ang' => 1.85200000000000E+13,
210 'Pica' => 5.24976377952723E+06
211 ),
212 'in' => array( 'm' => 2.54000000000000E-02,
213 'mi' => 1.57828282828283E-05,
214 'Nmi' => 1.37149028077754E-05,
215 'in' => 1.0,
216 'ft' => 8.33333333333333E-02,
217 'yd' => 2.77777777686643E-02,
218 'ang' => 2.54000000000000E+08,
219 'Pica' => 7.19999999999955E+01
220 ),
221 'ft' => array( 'm' => 3.04800000000000E-01,
222 'mi' => 1.89393939393939E-04,
223 'Nmi' => 1.64578833693305E-04,
224 'in' => 1.20000000000000E+01,
225 'ft' => 1.0,
226 'yd' => 3.33333333223972E-01,
227 'ang' => 3.04800000000000E+09,
228 'Pica' => 8.63999999999946E+02
229 ),
230 'yd' => array( 'm' => 9.14400000300000E-01,
231 'mi' => 5.68181818368230E-04,
232 'Nmi' => 4.93736501241901E-04,
233 'in' => 3.60000000118110E+01,
234 'ft' => 3.00000000000000E+00,
235 'yd' => 1.0,
236 'ang' => 9.14400000300000E+09,
237 'Pica' => 2.59200000085023E+03
238 ),
239 'ang' => array( 'm' => 1.00000000000000E-10,
240 'mi' => 6.21371192237334E-14,
241 'Nmi' => 5.39956803455724E-14,
242 'in' => 3.93700787401575E-09,
243 'ft' => 3.28083989501312E-10,
244 'yd' => 1.09361329797891E-10,
245 'ang' => 1.0,
246 'Pica' => 2.83464566929116E-07
247 ),
248 'Pica' => array( 'm' => 3.52777777777800E-04,
249 'mi' => 2.19205948372629E-07,
250 'Nmi' => 1.90484761219114E-07,
251 'in' => 1.38888888888898E-02,
252 'ft' => 1.15740740740748E-03,
253 'yd' => 3.85802469009251E-04,
254 'ang' => 3.52777777777800E+06,
255 'Pica' => 1.0
256 )
257 ),
258 'Time' => array( 'yr' => array( 'yr' => 1.0,
259 'day' => 365.25,
260 'hr' => 8766.0,
261 'mn' => 525960.0,
262 'sec' => 31557600.0
263 ),
264 'day' => array( 'yr' => 2.73785078713210E-03,
265 'day' => 1.0,
266 'hr' => 24.0,
267 'mn' => 1440.0,
268 'sec' => 86400.0
269 ),
270 'hr' => array( 'yr' => 1.14077116130504E-04,
271 'day' => 4.16666666666667E-02,
272 'hr' => 1.0,
273 'mn' => 60.0,
274 'sec' => 3600.0
275 ),
276 'mn' => array( 'yr' => 1.90128526884174E-06,
277 'day' => 6.94444444444444E-04,
278 'hr' => 1.66666666666667E-02,
279 'mn' => 1.0,
280 'sec' => 60.0
281 ),
282 'sec' => array( 'yr' => 3.16880878140289E-08,
283 'day' => 1.15740740740741E-05,
284 'hr' => 2.77777777777778E-04,
285 'mn' => 1.66666666666667E-02,
286 'sec' => 1.0
287 )
288 ),
289 'Pressure' => array( 'Pa' => array( 'Pa' => 1.0,
290 'p' => 1.0,
291 'atm' => 9.86923299998193E-06,
292 'at' => 9.86923299998193E-06,
293 'mmHg' => 7.50061707998627E-03
294 ),
295 'p' => array( 'Pa' => 1.0,
296 'p' => 1.0,
297 'atm' => 9.86923299998193E-06,
298 'at' => 9.86923299998193E-06,
299 'mmHg' => 7.50061707998627E-03
300 ),
301 'atm' => array( 'Pa' => 1.01324996583000E+05,
302 'p' => 1.01324996583000E+05,
303 'atm' => 1.0,
304 'at' => 1.0,
305 'mmHg' => 760.0
306 ),
307 'at' => array( 'Pa' => 1.01324996583000E+05,
308 'p' => 1.01324996583000E+05,
309 'atm' => 1.0,
310 'at' => 1.0,
311 'mmHg' => 760.0
312 ),
313 'mmHg' => array( 'Pa' => 1.33322363925000E+02,
314 'p' => 1.33322363925000E+02,
315 'atm' => 1.31578947368421E-03,
316 'at' => 1.31578947368421E-03,
317 'mmHg' => 1.0
318 )
319 ),
320 'Force' => array( 'N' => array( 'N' => 1.0,
321 'dyn' => 1.0E+5,
322 'dy' => 1.0E+5,
323 'lbf' => 2.24808923655339E-01
324 ),
325 'dyn' => array( 'N' => 1.0E-5,
326 'dyn' => 1.0,
327 'dy' => 1.0,
328 'lbf' => 2.24808923655339E-06
329 ),
330 'dy' => array( 'N' => 1.0E-5,
331 'dyn' => 1.0,
332 'dy' => 1.0,
333 'lbf' => 2.24808923655339E-06
334 ),
335 'lbf' => array( 'N' => 4.448222,
336 'dyn' => 4.448222E+5,
337 'dy' => 4.448222E+5,
338 'lbf' => 1.0
339 )
340 ),
341 'Energy' => array( 'J' => array( 'J' => 1.0,
342 'e' => 9.99999519343231E+06,
343 'c' => 2.39006249473467E-01,
344 'cal' => 2.38846190642017E-01,
345 'eV' => 6.24145700000000E+18,
346 'ev' => 6.24145700000000E+18,
347 'HPh' => 3.72506430801000E-07,
348 'hh' => 3.72506430801000E-07,
349 'Wh' => 2.77777916238711E-04,
350 'wh' => 2.77777916238711E-04,
351 'flb' => 2.37304222192651E+01,
352 'BTU' => 9.47815067349015E-04,
353 'btu' => 9.47815067349015E-04
354 ),
355 'e' => array( 'J' => 1.00000048065700E-07,
356 'e' => 1.0,
357 'c' => 2.39006364353494E-08,
358 'cal' => 2.38846305445111E-08,
359 'eV' => 6.24146000000000E+11,
360 'ev' => 6.24146000000000E+11,
361 'HPh' => 3.72506609848824E-14,
362 'hh' => 3.72506609848824E-14,
363 'Wh' => 2.77778049754611E-11,
364 'wh' => 2.77778049754611E-11,
365 'flb' => 2.37304336254586E-06,
366 'BTU' => 9.47815522922962E-11,
367 'btu' => 9.47815522922962E-11
368 ),
369 'c' => array( 'J' => 4.18399101363672E+00,
370 'e' => 4.18398900257312E+07,
371 'c' => 1.0,
372 'cal' => 9.99330315287563E-01,
373 'eV' => 2.61142000000000E+19,
374 'ev' => 2.61142000000000E+19,
375 'HPh' => 1.55856355899327E-06,
376 'hh' => 1.55856355899327E-06,
377 'Wh' => 1.16222030532950E-03,
378 'wh' => 1.16222030532950E-03,
379 'flb' => 9.92878733152102E+01,
380 'BTU' => 3.96564972437776E-03,
381 'btu' => 3.96564972437776E-03
382 ),
383 'cal' => array( 'J' => 4.18679484613929E+00,
384 'e' => 4.18679283372801E+07,
385 'c' => 1.00067013349059E+00,
386 'cal' => 1.0,
387 'eV' => 2.61317000000000E+19,
388 'ev' => 2.61317000000000E+19,
389 'HPh' => 1.55960800463137E-06,
390 'hh' => 1.55960800463137E-06,
391 'Wh' => 1.16299914807955E-03,
392 'wh' => 1.16299914807955E-03,
393 'flb' => 9.93544094443283E+01,
394 'BTU' => 3.96830723907002E-03,
395 'btu' => 3.96830723907002E-03
396 ),
397 'eV' => array( 'J' => 1.60219000146921E-19,
398 'e' => 1.60218923136574E-12,
399 'c' => 3.82933423195043E-20,
400 'cal' => 3.82676978535648E-20,
401 'eV' => 1.0,
402 'ev' => 1.0,
403 'HPh' => 5.96826078912344E-26,
404 'hh' => 5.96826078912344E-26,
405 'Wh' => 4.45053000026614E-23,
406 'wh' => 4.45053000026614E-23,
407 'flb' => 3.80206452103492E-18,
408 'BTU' => 1.51857982414846E-22,
409 'btu' => 1.51857982414846E-22
410 ),
411 'ev' => array( 'J' => 1.60219000146921E-19,
412 'e' => 1.60218923136574E-12,
413 'c' => 3.82933423195043E-20,
414 'cal' => 3.82676978535648E-20,
415 'eV' => 1.0,
416 'ev' => 1.0,
417 'HPh' => 5.96826078912344E-26,
418 'hh' => 5.96826078912344E-26,
419 'Wh' => 4.45053000026614E-23,
420 'wh' => 4.45053000026614E-23,
421 'flb' => 3.80206452103492E-18,
422 'BTU' => 1.51857982414846E-22,
423 'btu' => 1.51857982414846E-22
424 ),
425 'HPh' => array( 'J' => 2.68451741316170E+06,
426 'e' => 2.68451612283024E+13,
427 'c' => 6.41616438565991E+05,
428 'cal' => 6.41186757845835E+05,
429 'eV' => 1.67553000000000E+25,
430 'ev' => 1.67553000000000E+25,
431 'HPh' => 1.0,
432 'hh' => 1.0,
433 'Wh' => 7.45699653134593E+02,
434 'wh' => 7.45699653134593E+02,
435 'flb' => 6.37047316692964E+07,
436 'BTU' => 2.54442605275546E+03,
437 'btu' => 2.54442605275546E+03
438 ),
439 'hh' => array( 'J' => 2.68451741316170E+06,
440 'e' => 2.68451612283024E+13,
441 'c' => 6.41616438565991E+05,
442 'cal' => 6.41186757845835E+05,
443 'eV' => 1.67553000000000E+25,
444 'ev' => 1.67553000000000E+25,
445 'HPh' => 1.0,
446 'hh' => 1.0,
447 'Wh' => 7.45699653134593E+02,
448 'wh' => 7.45699653134593E+02,
449 'flb' => 6.37047316692964E+07,
450 'BTU' => 2.54442605275546E+03,
451 'btu' => 2.54442605275546E+03
452 ),
453 'Wh' => array( 'J' => 3.59999820554720E+03,
454 'e' => 3.59999647518369E+10,
455 'c' => 8.60422069219046E+02,
456 'cal' => 8.59845857713046E+02,
457 'eV' => 2.24692340000000E+22,
458 'ev' => 2.24692340000000E+22,
459 'HPh' => 1.34102248243839E-03,
460 'hh' => 1.34102248243839E-03,
461 'Wh' => 1.0,
462 'wh' => 1.0,
463 'flb' => 8.54294774062316E+04,
464 'BTU' => 3.41213254164705E+00,
465 'btu' => 3.41213254164705E+00
466 ),
467 'wh' => array( 'J' => 3.59999820554720E+03,
468 'e' => 3.59999647518369E+10,
469 'c' => 8.60422069219046E+02,
470 'cal' => 8.59845857713046E+02,
471 'eV' => 2.24692340000000E+22,
472 'ev' => 2.24692340000000E+22,
473 'HPh' => 1.34102248243839E-03,
474 'hh' => 1.34102248243839E-03,
475 'Wh' => 1.0,
476 'wh' => 1.0,
477 'flb' => 8.54294774062316E+04,
478 'BTU' => 3.41213254164705E+00,
479 'btu' => 3.41213254164705E+00
480 ),
481 'flb' => array( 'J' => 4.21400003236424E-02,
482 'e' => 4.21399800687660E+05,
483 'c' => 1.00717234301644E-02,
484 'cal' => 1.00649785509554E-02,
485 'eV' => 2.63015000000000E+17,
486 'ev' => 2.63015000000000E+17,
487 'HPh' => 1.56974211145130E-08,
488 'hh' => 1.56974211145130E-08,
489 'Wh' => 1.17055614802000E-05,
490 'wh' => 1.17055614802000E-05,
491 'flb' => 1.0,
492 'BTU' => 3.99409272448406E-05,
493 'btu' => 3.99409272448406E-05
494 ),
495 'BTU' => array( 'J' => 1.05505813786749E+03,
496 'e' => 1.05505763074665E+10,
497 'c' => 2.52165488508168E+02,
498 'cal' => 2.51996617135510E+02,
499 'eV' => 6.58510000000000E+21,
500 'ev' => 6.58510000000000E+21,
501 'HPh' => 3.93015941224568E-04,
502 'hh' => 3.93015941224568E-04,
503 'Wh' => 2.93071851047526E-01,
504 'wh' => 2.93071851047526E-01,
505 'flb' => 2.50369750774671E+04,
506 'BTU' => 1.0,
507 'btu' => 1.0,
508 ),
509 'btu' => array( 'J' => 1.05505813786749E+03,
510 'e' => 1.05505763074665E+10,
511 'c' => 2.52165488508168E+02,
512 'cal' => 2.51996617135510E+02,
513 'eV' => 6.58510000000000E+21,
514 'ev' => 6.58510000000000E+21,
515 'HPh' => 3.93015941224568E-04,
516 'hh' => 3.93015941224568E-04,
517 'Wh' => 2.93071851047526E-01,
518 'wh' => 2.93071851047526E-01,
519 'flb' => 2.50369750774671E+04,
520 'BTU' => 1.0,
521 'btu' => 1.0,
522 )
523 ),
524 'Power' => array( 'HP' => array( 'HP' => 1.0,
525 'h' => 1.0,
526 'W' => 7.45701000000000E+02,
527 'w' => 7.45701000000000E+02
528 ),
529 'h' => array( 'HP' => 1.0,
530 'h' => 1.0,
531 'W' => 7.45701000000000E+02,
532 'w' => 7.45701000000000E+02
533 ),
534 'W' => array( 'HP' => 1.34102006031908E-03,
535 'h' => 1.34102006031908E-03,
536 'W' => 1.0,
537 'w' => 1.0
538 ),
539 'w' => array( 'HP' => 1.34102006031908E-03,
540 'h' => 1.34102006031908E-03,
541 'W' => 1.0,
542 'w' => 1.0
543 )
544 ),
545 'Magnetism' => array( 'T' => array( 'T' => 1.0,
546 'ga' => 10000.0
547 ),
548 'ga' => array( 'T' => 0.0001,
549 'ga' => 1.0
550 )
551 ),
552 'Liquid' => array( 'tsp' => array( 'tsp' => 1.0,
553 'tbs' => 3.33333333333333E-01,
554 'oz' => 1.66666666666667E-01,
555 'cup' => 2.08333333333333E-02,
556 'pt' => 1.04166666666667E-02,
557 'us_pt' => 1.04166666666667E-02,
558 'uk_pt' => 8.67558516821960E-03,
559 'qt' => 5.20833333333333E-03,
560 'gal' => 1.30208333333333E-03,
561 'l' => 4.92999408400710E-03,
562 'lt' => 4.92999408400710E-03
563 ),
564 'tbs' => array( 'tsp' => 3.00000000000000E+00,
565 'tbs' => 1.0,
566 'oz' => 5.00000000000000E-01,
567 'cup' => 6.25000000000000E-02,
568 'pt' => 3.12500000000000E-02,
569 'us_pt' => 3.12500000000000E-02,
570 'uk_pt' => 2.60267555046588E-02,
571 'qt' => 1.56250000000000E-02,
572 'gal' => 3.90625000000000E-03,
573 'l' => 1.47899822520213E-02,
574 'lt' => 1.47899822520213E-02
575 ),
576 'oz' => array( 'tsp' => 6.00000000000000E+00,
577 'tbs' => 2.00000000000000E+00,
578 'oz' => 1.0,
579 'cup' => 1.25000000000000E-01,
580 'pt' => 6.25000000000000E-02,
581 'us_pt' => 6.25000000000000E-02,
582 'uk_pt' => 5.20535110093176E-02,
583 'qt' => 3.12500000000000E-02,
584 'gal' => 7.81250000000000E-03,
585 'l' => 2.95799645040426E-02,
586 'lt' => 2.95799645040426E-02
587 ),
588 'cup' => array( 'tsp' => 4.80000000000000E+01,
589 'tbs' => 1.60000000000000E+01,
590 'oz' => 8.00000000000000E+00,
591 'cup' => 1.0,
592 'pt' => 5.00000000000000E-01,
593 'us_pt' => 5.00000000000000E-01,
594 'uk_pt' => 4.16428088074541E-01,
595 'qt' => 2.50000000000000E-01,
596 'gal' => 6.25000000000000E-02,
597 'l' => 2.36639716032341E-01,
598 'lt' => 2.36639716032341E-01
599 ),
600 'pt' => array( 'tsp' => 9.60000000000000E+01,
601 'tbs' => 3.20000000000000E+01,
602 'oz' => 1.60000000000000E+01,
603 'cup' => 2.00000000000000E+00,
604 'pt' => 1.0,
605 'us_pt' => 1.0,
606 'uk_pt' => 8.32856176149081E-01,
607 'qt' => 5.00000000000000E-01,
608 'gal' => 1.25000000000000E-01,
609 'l' => 4.73279432064682E-01,
610 'lt' => 4.73279432064682E-01
611 ),
612 'us_pt' => array( 'tsp' => 9.60000000000000E+01,
613 'tbs' => 3.20000000000000E+01,
614 'oz' => 1.60000000000000E+01,
615 'cup' => 2.00000000000000E+00,
616 'pt' => 1.0,
617 'us_pt' => 1.0,
618 'uk_pt' => 8.32856176149081E-01,
619 'qt' => 5.00000000000000E-01,
620 'gal' => 1.25000000000000E-01,
621 'l' => 4.73279432064682E-01,
622 'lt' => 4.73279432064682E-01
623 ),
624 'uk_pt' => array( 'tsp' => 1.15266000000000E+02,
625 'tbs' => 3.84220000000000E+01,
626 'oz' => 1.92110000000000E+01,
627 'cup' => 2.40137500000000E+00,
628 'pt' => 1.20068750000000E+00,
629 'us_pt' => 1.20068750000000E+00,
630 'uk_pt' => 1.0,
631 'qt' => 6.00343750000000E-01,
632 'gal' => 1.50085937500000E-01,
633 'l' => 5.68260698087162E-01,
634 'lt' => 5.68260698087162E-01
635 ),
636 'qt' => array( 'tsp' => 1.92000000000000E+02,
637 'tbs' => 6.40000000000000E+01,
638 'oz' => 3.20000000000000E+01,
639 'cup' => 4.00000000000000E+00,
640 'pt' => 2.00000000000000E+00,
641 'us_pt' => 2.00000000000000E+00,
642 'uk_pt' => 1.66571235229816E+00,
643 'qt' => 1.0,
644 'gal' => 2.50000000000000E-01,
645 'l' => 9.46558864129363E-01,
646 'lt' => 9.46558864129363E-01
647 ),
648 'gal' => array( 'tsp' => 7.68000000000000E+02,
649 'tbs' => 2.56000000000000E+02,
650 'oz' => 1.28000000000000E+02,
651 'cup' => 1.60000000000000E+01,
652 'pt' => 8.00000000000000E+00,
653 'us_pt' => 8.00000000000000E+00,
654 'uk_pt' => 6.66284940919265E+00,
655 'qt' => 4.00000000000000E+00,
656 'gal' => 1.0,
657 'l' => 3.78623545651745E+00,
658 'lt' => 3.78623545651745E+00
659 ),
660 'l' => array( 'tsp' => 2.02840000000000E+02,
661 'tbs' => 6.76133333333333E+01,
662 'oz' => 3.38066666666667E+01,
663 'cup' => 4.22583333333333E+00,
664 'pt' => 2.11291666666667E+00,
665 'us_pt' => 2.11291666666667E+00,
666 'uk_pt' => 1.75975569552166E+00,
667 'qt' => 1.05645833333333E+00,
668 'gal' => 2.64114583333333E-01,
669 'l' => 1.0,
670 'lt' => 1.0
671 ),
672 'lt' => array( 'tsp' => 2.02840000000000E+02,
673 'tbs' => 6.76133333333333E+01,
674 'oz' => 3.38066666666667E+01,
675 'cup' => 4.22583333333333E+00,
676 'pt' => 2.11291666666667E+00,
677 'us_pt' => 2.11291666666667E+00,
678 'uk_pt' => 1.75975569552166E+00,
679 'qt' => 1.05645833333333E+00,
680 'gal' => 2.64114583333333E-01,
681 'l' => 1.0,
682 'lt' => 1.0
683 )
684 )
685 );
686
687
688 /**
689 * _parseComplex
690 *
691 * Parses a complex number into its real and imaginary parts, and an I or J suffix
692 *
693 * @param string $complexNumber The complex number
694 * @return string[] Indexed on "real", "imaginary" and "suffix"
695 */
696 public static function _parseComplex($complexNumber) {
697 $workString = (string) $complexNumber;
698
699 $realNumber = $imaginary = 0;
700 // Extract the suffix, if there is one
701 $suffix = substr($workString,-1);
702 if (!is_numeric($suffix)) {
703 $workString = substr($workString,0,-1);
704 } else {
705 $suffix = '';
706 }
707
708 // Split the input into its Real and Imaginary components
709 $leadingSign = 0;
710 if (strlen($workString) > 0) {
711 $leadingSign = (($workString{0} == '+') || ($workString{0} == '-')) ? 1 : 0;
712 }
713 $power = '';
714 $realNumber = strtok($workString, '+-');
715 if (strtoupper(substr($realNumber,-1)) == 'E') {
716 $power = strtok('+-');
717 ++$leadingSign;
718 }
719
720 $realNumber = substr($workString,0,strlen($realNumber)+strlen($power)+$leadingSign);
721
722 if ($suffix != '') {
723 $imaginary = substr($workString,strlen($realNumber));
724
725 if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) {
726 $imaginary = $realNumber.'1';
727 $realNumber = '0';
728 } else if ($imaginary == '') {
729 $imaginary = $realNumber;
730 $realNumber = '0';
731 } elseif (($imaginary == '+') || ($imaginary == '-')) {
732 $imaginary .= '1';
733 }
734 }
735
736 return array( 'real' => $realNumber,
737 'imaginary' => $imaginary,
738 'suffix' => $suffix
739 );
740 } // function _parseComplex()
741
742
743 /**
744 * Cleans the leading characters in a complex number string
745 *
746 * @param string $complexNumber The complex number to clean
747 * @return string The "cleaned" complex number
748 */
749 private static function _cleanComplex($complexNumber) {
750 if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1);
751 if ($complexNumber{0} == '0') $complexNumber = substr($complexNumber,1);
752 if ($complexNumber{0} == '.') $complexNumber = '0'.$complexNumber;
753 if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1);
754 return $complexNumber;
755 }
756
757 /**
758 * Formats a number base string value with leading zeroes
759 *
760 * @param string $xVal The "number" to pad
761 * @param integer $places The length that we want to pad this value
762 * @return string The padded "number"
763 */
764 private static function _nbrConversionFormat($xVal, $places) {
765 if (!is_null($places)) {
766 if (strlen($xVal) <= $places) {
767 return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10);
768 } else {
769 return PHPExcel_Calculation_Functions::NaN();
770 }
771 }
772
773 return substr($xVal, -10);
774 } // function _nbrConversionFormat()
775
776 /**
777 * BESSELI
778 *
779 * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated
780 * for purely imaginary arguments
781 *
782 * Excel Function:
783 * BESSELI(x,ord)
784 *
785 * @access public
786 * @category Engineering Functions
787 * @param float $x The value at which to evaluate the function.
788 * If x is nonnumeric, BESSELI returns the #VALUE! error value.
789 * @param integer $ord The order of the Bessel function.
790 * If ord is not an integer, it is truncated.
791 * If $ord is nonnumeric, BESSELI returns the #VALUE! error value.
792 * If $ord < 0, BESSELI returns the #NUM! error value.
793 * @return float
794 *
795 */
796 public static function BESSELI($x, $ord) {
797 $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x);
798 $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord);
799
800 if ((is_numeric($x)) && (is_numeric($ord))) {
801 $ord = floor($ord);
802 if ($ord < 0) {
803 return PHPExcel_Calculation_Functions::NaN();
804 }
805
806 if (abs($x) <= 30) {
807 $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord);
808 $ordK = 1;
809 $fSqrX = ($x * $x) / 4;
810 do {
811 $fTerm *= $fSqrX;
812 $fTerm /= ($ordK * ($ordK + $ord));
813 $fResult += $fTerm;
814 } while ((abs($fTerm) > 1e-12) && (++$ordK < 100));
815 } else {
816 $f_2_PI = 2 * M_PI;
817
818 $fXAbs = abs($x);
819 $fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs);
820 if (($ord & 1) && ($x < 0)) {
821 $fResult = -$fResult;
822 }
823 }
824 return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult;
825 }
826 return PHPExcel_Calculation_Functions::VALUE();
827 } // function BESSELI()
828
829
830 /**
831 * BESSELJ
832 *
833 * Returns the Bessel function
834 *
835 * Excel Function:
836 * BESSELJ(x,ord)
837 *
838 * @access public
839 * @category Engineering Functions
840 * @param float $x The value at which to evaluate the function.
841 * If x is nonnumeric, BESSELJ returns the #VALUE! error value.
842 * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated.
843 * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value.
844 * If $ord < 0, BESSELJ returns the #NUM! error value.
845 * @return float
846 *
847 */
848 public static function BESSELJ($x, $ord) {
849 $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x);
850 $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord);
851
852 if ((is_numeric($x)) && (is_numeric($ord))) {
853 $ord = floor($ord);
854 if ($ord < 0) {
855 return PHPExcel_Calculation_Functions::NaN();
856 }
857
858 $fResult = 0;
859 if (abs($x) <= 30) {
860 $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord);
861 $ordK = 1;
862 $fSqrX = ($x * $x) / -4;
863 do {
864 $fTerm *= $fSqrX;
865 $fTerm /= ($ordK * ($ordK + $ord));
866 $fResult += $fTerm;
867 } while ((abs($fTerm) > 1e-12) && (++$ordK < 100));
868 } else {
869 $f_PI_DIV_2 = M_PI / 2;
870 $f_PI_DIV_4 = M_PI / 4;
871
872 $fXAbs = abs($x);
873 $fResult = sqrt(M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4);
874 if (($ord & 1) && ($x < 0)) {
875 $fResult = -$fResult;
876 }
877 }
878 return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult;
879 }
880 return PHPExcel_Calculation_Functions::VALUE();
881 } // function BESSELJ()
882
883
884 private static function _Besselk0($fNum) {
885 if ($fNum <= 2) {
886 $fNum2 = $fNum * 0.5;
887 $y = ($fNum2 * $fNum2);
888 $fRet = -log($fNum2) * self::BESSELI($fNum, 0) +
889 (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y *
890 (0.10750e-3 + $y * 0.74e-5))))));
891 } else {
892 $y = 2 / $fNum;
893 $fRet = exp(-$fNum) / sqrt($fNum) *
894 (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y *
895 (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3))))));
896 }
897 return $fRet;
898 } // function _Besselk0()
899
900
901 private static function _Besselk1($fNum) {
902 if ($fNum <= 2) {
903 $fNum2 = $fNum * 0.5;
904 $y = ($fNum2 * $fNum2);
905 $fRet = log($fNum2) * self::BESSELI($fNum, 1) +
906 (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y *
907 (-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum;
908 } else {
909 $y = 2 / $fNum;
910 $fRet = exp(-$fNum) / sqrt($fNum) *
911 (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y *
912 (0.325614e-2 + $y * (-0.68245e-3)))))));
913 }
914 return $fRet;
915 } // function _Besselk1()
916
917
918 /**
919 * BESSELK
920 *
921 * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated
922 * for purely imaginary arguments.
923 *
924 * Excel Function:
925 * BESSELK(x,ord)
926 *
927 * @access public
928 * @category Engineering Functions
929 * @param float $x The value at which to evaluate the function.
930 * If x is nonnumeric, BESSELK returns the #VALUE! error value.
931 * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated.
932 * If $ord is nonnumeric, BESSELK returns the #VALUE! error value.
933 * If $ord < 0, BESSELK returns the #NUM! error value.
934 * @return float
935 *
936 */
937 public static function BESSELK($x, $ord) {
938 $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x);
939 $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord);
940
941 if ((is_numeric($x)) && (is_numeric($ord))) {
942 if (($ord < 0) || ($x == 0.0)) {
943 return PHPExcel_Calculation_Functions::NaN();
944 }
945
946 switch(floor($ord)) {
947 case 0 : return self::_Besselk0($x);
948 break;
949 case 1 : return self::_Besselk1($x);
950 break;
951 default : $fTox = 2 / $x;
952 $fBkm = self::_Besselk0($x);
953 $fBk = self::_Besselk1($x);
954 for ($n = 1; $n < $ord; ++$n) {
955 $fBkp = $fBkm + $n * $fTox * $fBk;
956 $fBkm = $fBk;
957 $fBk = $fBkp;
958 }
959 }
960 return (is_nan($fBk)) ? PHPExcel_Calculation_Functions::NaN() : $fBk;
961 }
962 return PHPExcel_Calculation_Functions::VALUE();
963 } // function BESSELK()
964
965
966 private static function _Bessely0($fNum) {
967 if ($fNum < 8.0) {
968 $y = ($fNum * $fNum);
969 $f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733))));
970 $f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y))));
971 $fRet = $f1 / $f2 + 0.636619772 * self::BESSELJ($fNum, 0) * log($fNum);
972 } else {
973 $z = 8.0 / $fNum;
974 $y = ($z * $z);
975 $xx = $fNum - 0.785398164;
976 $f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6)));
977 $f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7))));
978 $fRet = sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2);
979 }
980 return $fRet;
981 } // function _Bessely0()
982
983
984 private static function _Bessely1($fNum) {
985 if ($fNum < 8.0) {
986 $y = ($fNum * $fNum);
987 $f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y *
988 (-0.4237922726e7 + $y * 0.8511937935e4)))));
989 $f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y *
990 (0.1020426050e6 + $y * (0.3549632885e3 + $y)))));
991 $fRet = $f1 / $f2 + 0.636619772 * ( self::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum);
992 } else {
993 $fRet = sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491);
994 }
995 return $fRet;
996 } // function _Bessely1()
997
998
999 /**
1000 * BESSELY
1001 *
1002 * Returns the Bessel function, which is also called the Weber function or the Neumann function.
1003 *
1004 * Excel Function:
1005 * BESSELY(x,ord)
1006 *
1007 * @access public
1008 * @category Engineering Functions
1009 * @param float $x The value at which to evaluate the function.
1010 * If x is nonnumeric, BESSELK returns the #VALUE! error value.
1011 * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated.
1012 * If $ord is nonnumeric, BESSELK returns the #VALUE! error value.
1013 * If $ord < 0, BESSELK returns the #NUM! error value.
1014 *
1015 * @return float
1016 */
1017 public static function BESSELY($x, $ord) {
1018 $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x);
1019 $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord);
1020
1021 if ((is_numeric($x)) && (is_numeric($ord))) {
1022 if (($ord < 0) || ($x == 0.0)) {
1023 return PHPExcel_Calculation_Functions::NaN();
1024 }
1025
1026 switch(floor($ord)) {
1027 case 0 : return self::_Bessely0($x);
1028 break;
1029 case 1 : return self::_Bessely1($x);
1030 break;
1031 default: $fTox = 2 / $x;
1032 $fBym = self::_Bessely0($x);
1033 $fBy = self::_Bessely1($x);
1034 for ($n = 1; $n < $ord; ++$n) {
1035 $fByp = $n * $fTox * $fBy - $fBym;
1036 $fBym = $fBy;
1037 $fBy = $fByp;
1038 }
1039 }
1040 return (is_nan($fBy)) ? PHPExcel_Calculation_Functions::NaN() : $fBy;
1041 }
1042 return PHPExcel_Calculation_Functions::VALUE();
1043 } // function BESSELY()
1044
1045
1046 /**
1047 * BINTODEC
1048 *
1049 * Return a binary value as decimal.
1050 *
1051 * Excel Function:
1052 * BIN2DEC(x)
1053 *
1054 * @access public
1055 * @category Engineering Functions
1056 * @param string $x The binary number (as a string) that you want to convert. The number
1057 * cannot contain more than 10 characters (10 bits). The most significant
1058 * bit of number is the sign bit. The remaining 9 bits are magnitude bits.
1059 * Negative numbers are represented using two's-complement notation.
1060 * If number is not a valid binary number, or if number contains more than
1061 * 10 characters (10 bits), BIN2DEC returns the #NUM! error value.
1062 * @return string
1063 */
1064 public static function BINTODEC($x) {
1065 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1066
1067 if (is_bool($x)) {
1068 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
1069 $x = (int) $x;
1070 } else {
1071 return PHPExcel_Calculation_Functions::VALUE();
1072 }
1073 }
1074 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {
1075 $x = floor($x);
1076 }
1077 $x = (string) $x;
1078 if (strlen($x) > preg_match_all('/[01]/',$x,$out)) {
1079 return PHPExcel_Calculation_Functions::NaN();
1080 }
1081 if (strlen($x) > 10) {
1082 return PHPExcel_Calculation_Functions::NaN();
1083 } elseif (strlen($x) == 10) {
1084 // Two's Complement
1085 $x = substr($x,-9);
1086 return '-'.(512-bindec($x));
1087 }
1088 return bindec($x);
1089 } // function BINTODEC()
1090
1091
1092 /**
1093 * BINTOHEX
1094 *
1095 * Return a binary value as hex.
1096 *
1097 * Excel Function:
1098 * BIN2HEX(x[,places])
1099 *
1100 * @access public
1101 * @category Engineering Functions
1102 * @param string $x The binary number (as a string) that you want to convert. The number
1103 * cannot contain more than 10 characters (10 bits). The most significant
1104 * bit of number is the sign bit. The remaining 9 bits are magnitude bits.
1105 * Negative numbers are represented using two's-complement notation.
1106 * If number is not a valid binary number, or if number contains more than
1107 * 10 characters (10 bits), BIN2HEX returns the #NUM! error value.
1108 * @param integer $places The number of characters to use. If places is omitted, BIN2HEX uses the
1109 * minimum number of characters necessary. Places is useful for padding the
1110 * return value with leading 0s (zeros).
1111 * If places is not an integer, it is truncated.
1112 * If places is nonnumeric, BIN2HEX returns the #VALUE! error value.
1113 * If places is negative, BIN2HEX returns the #NUM! error value.
1114 * @return string
1115 */
1116 public static function BINTOHEX($x, $places=NULL) {
1117 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1118 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1119
1120 if (is_bool($x)) {
1121 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
1122 $x = (int) $x;
1123 } else {
1124 return PHPExcel_Calculation_Functions::VALUE();
1125 }
1126 }
1127 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {
1128 $x = floor($x);
1129 }
1130 $x = (string) $x;
1131 if (strlen($x) > preg_match_all('/[01]/',$x,$out)) {
1132 return PHPExcel_Calculation_Functions::NaN();
1133 }
1134 if (strlen($x) > 10) {
1135 return PHPExcel_Calculation_Functions::NaN();
1136 } elseif (strlen($x) == 10) {
1137 // Two's Complement
1138 return str_repeat('F',8).substr(strtoupper(dechex(bindec(substr($x,-9)))),-2);
1139 }
1140 $hexVal = (string) strtoupper(dechex(bindec($x)));
1141
1142 return self::_nbrConversionFormat($hexVal,$places);
1143 } // function BINTOHEX()
1144
1145
1146 /**
1147 * BINTOOCT
1148 *
1149 * Return a binary value as octal.
1150 *
1151 * Excel Function:
1152 * BIN2OCT(x[,places])
1153 *
1154 * @access public
1155 * @category Engineering Functions
1156 * @param string $x The binary number (as a string) that you want to convert. The number
1157 * cannot contain more than 10 characters (10 bits). The most significant
1158 * bit of number is the sign bit. The remaining 9 bits are magnitude bits.
1159 * Negative numbers are represented using two's-complement notation.
1160 * If number is not a valid binary number, or if number contains more than
1161 * 10 characters (10 bits), BIN2OCT returns the #NUM! error value.
1162 * @param integer $places The number of characters to use. If places is omitted, BIN2OCT uses the
1163 * minimum number of characters necessary. Places is useful for padding the
1164 * return value with leading 0s (zeros).
1165 * If places is not an integer, it is truncated.
1166 * If places is nonnumeric, BIN2OCT returns the #VALUE! error value.
1167 * If places is negative, BIN2OCT returns the #NUM! error value.
1168 * @return string
1169 */
1170 public static function BINTOOCT($x, $places=NULL) {
1171 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1172 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1173
1174 if (is_bool($x)) {
1175 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
1176 $x = (int) $x;
1177 } else {
1178 return PHPExcel_Calculation_Functions::VALUE();
1179 }
1180 }
1181 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {
1182 $x = floor($x);
1183 }
1184 $x = (string) $x;
1185 if (strlen($x) > preg_match_all('/[01]/',$x,$out)) {
1186 return PHPExcel_Calculation_Functions::NaN();
1187 }
1188 if (strlen($x) > 10) {
1189 return PHPExcel_Calculation_Functions::NaN();
1190 } elseif (strlen($x) == 10) {
1191 // Two's Complement
1192 return str_repeat('7',7).substr(strtoupper(decoct(bindec(substr($x,-9)))),-3);
1193 }
1194 $octVal = (string) decoct(bindec($x));
1195
1196 return self::_nbrConversionFormat($octVal,$places);
1197 } // function BINTOOCT()
1198
1199
1200 /**
1201 * DECTOBIN
1202 *
1203 * Return a decimal value as binary.
1204 *
1205 * Excel Function:
1206 * DEC2BIN(x[,places])
1207 *
1208 * @access public
1209 * @category Engineering Functions
1210 * @param string $x The decimal integer you want to convert. If number is negative,
1211 * valid place values are ignored and DEC2BIN returns a 10-character
1212 * (10-bit) binary number in which the most significant bit is the sign
1213 * bit. The remaining 9 bits are magnitude bits. Negative numbers are
1214 * represented using two's-complement notation.
1215 * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error
1216 * value.
1217 * If number is nonnumeric, DEC2BIN returns the #VALUE! error value.
1218 * If DEC2BIN requires more than places characters, it returns the #NUM!
1219 * error value.
1220 * @param integer $places The number of characters to use. If places is omitted, DEC2BIN uses
1221 * the minimum number of characters necessary. Places is useful for
1222 * padding the return value with leading 0s (zeros).
1223 * If places is not an integer, it is truncated.
1224 * If places is nonnumeric, DEC2BIN returns the #VALUE! error value.
1225 * If places is zero or negative, DEC2BIN returns the #NUM! error value.
1226 * @return string
1227 */
1228 public static function DECTOBIN($x, $places=NULL) {
1229 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1230 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1231
1232 if (is_bool($x)) {
1233 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
1234 $x = (int) $x;
1235 } else {
1236 return PHPExcel_Calculation_Functions::VALUE();
1237 }
1238 }
1239 $x = (string) $x;
1240 if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) {
1241 return PHPExcel_Calculation_Functions::VALUE();
1242 }
1243 $x = (string) floor($x);
1244 $r = decbin($x);
1245 if (strlen($r) == 32) {
1246 // Two's Complement
1247 $r = substr($r,-10);
1248 } elseif (strlen($r) > 11) {
1249 return PHPExcel_Calculation_Functions::NaN();
1250 }
1251
1252 return self::_nbrConversionFormat($r,$places);
1253 } // function DECTOBIN()
1254
1255
1256 /**
1257 * DECTOHEX
1258 *
1259 * Return a decimal value as hex.
1260 *
1261 * Excel Function:
1262 * DEC2HEX(x[,places])
1263 *
1264 * @access public
1265 * @category Engineering Functions
1266 * @param string $x The decimal integer you want to convert. If number is negative,
1267 * places is ignored and DEC2HEX returns a 10-character (40-bit)
1268 * hexadecimal number in which the most significant bit is the sign
1269 * bit. The remaining 39 bits are magnitude bits. Negative numbers
1270 * are represented using two's-complement notation.
1271 * If number < -549,755,813,888 or if number > 549,755,813,887,
1272 * DEC2HEX returns the #NUM! error value.
1273 * If number is nonnumeric, DEC2HEX returns the #VALUE! error value.
1274 * If DEC2HEX requires more than places characters, it returns the
1275 * #NUM! error value.
1276 * @param integer $places The number of characters to use. If places is omitted, DEC2HEX uses
1277 * the minimum number of characters necessary. Places is useful for
1278 * padding the return value with leading 0s (zeros).
1279 * If places is not an integer, it is truncated.
1280 * If places is nonnumeric, DEC2HEX returns the #VALUE! error value.
1281 * If places is zero or negative, DEC2HEX returns the #NUM! error value.
1282 * @return string
1283 */
1284 public static function DECTOHEX($x, $places=null) {
1285 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1286 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1287
1288 if (is_bool($x)) {
1289 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
1290 $x = (int) $x;
1291 } else {
1292 return PHPExcel_Calculation_Functions::VALUE();
1293 }
1294 }
1295 $x = (string) $x;
1296 if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) {
1297 return PHPExcel_Calculation_Functions::VALUE();
1298 }
1299 $x = (string) floor($x);
1300 $r = strtoupper(dechex($x));
1301 if (strlen($r) == 8) {
1302 // Two's Complement
1303 $r = 'FF'.$r;
1304 }
1305
1306 return self::_nbrConversionFormat($r,$places);
1307 } // function DECTOHEX()
1308
1309
1310 /**
1311 * DECTOOCT
1312 *
1313 * Return an decimal value as octal.
1314 *
1315 * Excel Function:
1316 * DEC2OCT(x[,places])
1317 *
1318 * @access public
1319 * @category Engineering Functions
1320 * @param string $x The decimal integer you want to convert. If number is negative,
1321 * places is ignored and DEC2OCT returns a 10-character (30-bit)
1322 * octal number in which the most significant bit is the sign bit.
1323 * The remaining 29 bits are magnitude bits. Negative numbers are
1324 * represented using two's-complement notation.
1325 * If number < -536,870,912 or if number > 536,870,911, DEC2OCT
1326 * returns the #NUM! error value.
1327 * If number is nonnumeric, DEC2OCT returns the #VALUE! error value.
1328 * If DEC2OCT requires more than places characters, it returns the
1329 * #NUM! error value.
1330 * @param integer $places The number of characters to use. If places is omitted, DEC2OCT uses
1331 * the minimum number of characters necessary. Places is useful for
1332 * padding the return value with leading 0s (zeros).
1333 * If places is not an integer, it is truncated.
1334 * If places is nonnumeric, DEC2OCT returns the #VALUE! error value.
1335 * If places is zero or negative, DEC2OCT returns the #NUM! error value.
1336 * @return string
1337 */
1338 public static function DECTOOCT($x, $places=null) {
1339 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1340 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1341
1342 if (is_bool($x)) {
1343 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
1344 $x = (int) $x;
1345 } else {
1346 return PHPExcel_Calculation_Functions::VALUE();
1347 }
1348 }
1349 $x = (string) $x;
1350 if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) {
1351 return PHPExcel_Calculation_Functions::VALUE();
1352 }
1353 $x = (string) floor($x);
1354 $r = decoct($x);
1355 if (strlen($r) == 11) {
1356 // Two's Complement
1357 $r = substr($r,-10);
1358 }
1359
1360 return self::_nbrConversionFormat($r,$places);
1361 } // function DECTOOCT()
1362
1363
1364 /**
1365 * HEXTOBIN
1366 *
1367 * Return a hex value as binary.
1368 *
1369 * Excel Function:
1370 * HEX2BIN(x[,places])
1371 *
1372 * @access public
1373 * @category Engineering Functions
1374 * @param string $x the hexadecimal number you want to convert. Number cannot
1375 * contain more than 10 characters. The most significant bit of
1376 * number is the sign bit (40th bit from the right). The remaining
1377 * 9 bits are magnitude bits. Negative numbers are represented
1378 * using two's-complement notation.
1379 * If number is negative, HEX2BIN ignores places and returns a
1380 * 10-character binary number.
1381 * If number is negative, it cannot be less than FFFFFFFE00, and
1382 * if number is positive, it cannot be greater than 1FF.
1383 * If number is not a valid hexadecimal number, HEX2BIN returns
1384 * the #NUM! error value.
1385 * If HEX2BIN requires more than places characters, it returns
1386 * the #NUM! error value.
1387 * @param integer $places The number of characters to use. If places is omitted,
1388 * HEX2BIN uses the minimum number of characters necessary. Places
1389 * is useful for padding the return value with leading 0s (zeros).
1390 * If places is not an integer, it is truncated.
1391 * If places is nonnumeric, HEX2BIN returns the #VALUE! error value.
1392 * If places is negative, HEX2BIN returns the #NUM! error value.
1393 * @return string
1394 */
1395 public static function HEXTOBIN($x, $places=null) {
1396 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1397 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1398
1399 if (is_bool($x)) {
1400 return PHPExcel_Calculation_Functions::VALUE();
1401 }
1402 $x = (string) $x;
1403 if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) {
1404 return PHPExcel_Calculation_Functions::NaN();
1405 }
1406 $binVal = decbin(hexdec($x));
1407
1408 return substr(self::_nbrConversionFormat($binVal,$places),-10);
1409 } // function HEXTOBIN()
1410
1411
1412 /**
1413 * HEXTODEC
1414 *
1415 * Return a hex value as decimal.
1416 *
1417 * Excel Function:
1418 * HEX2DEC(x)
1419 *
1420 * @access public
1421 * @category Engineering Functions
1422 * @param string $x The hexadecimal number you want to convert. This number cannot
1423 * contain more than 10 characters (40 bits). The most significant
1424 * bit of number is the sign bit. The remaining 39 bits are magnitude
1425 * bits. Negative numbers are represented using two's-complement
1426 * notation.
1427 * If number is not a valid hexadecimal number, HEX2DEC returns the
1428 * #NUM! error value.
1429 * @return string
1430 */
1431 public static function HEXTODEC($x) {
1432 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1433
1434 if (is_bool($x)) {
1435 return PHPExcel_Calculation_Functions::VALUE();
1436 }
1437 $x = (string) $x;
1438 if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) {
1439 return PHPExcel_Calculation_Functions::NaN();
1440 }
1441 return hexdec($x);
1442 } // function HEXTODEC()
1443
1444
1445 /**
1446 * HEXTOOCT
1447 *
1448 * Return a hex value as octal.
1449 *
1450 * Excel Function:
1451 * HEX2OCT(x[,places])
1452 *
1453 * @access public
1454 * @category Engineering Functions
1455 * @param string $x The hexadecimal number you want to convert. Number cannot
1456 * contain more than 10 characters. The most significant bit of
1457 * number is the sign bit. The remaining 39 bits are magnitude
1458 * bits. Negative numbers are represented using two's-complement
1459 * notation.
1460 * If number is negative, HEX2OCT ignores places and returns a
1461 * 10-character octal number.
1462 * If number is negative, it cannot be less than FFE0000000, and
1463 * if number is positive, it cannot be greater than 1FFFFFFF.
1464 * If number is not a valid hexadecimal number, HEX2OCT returns
1465 * the #NUM! error value.
1466 * If HEX2OCT requires more than places characters, it returns
1467 * the #NUM! error value.
1468 * @param integer $places The number of characters to use. If places is omitted, HEX2OCT
1469 * uses the minimum number of characters necessary. Places is
1470 * useful for padding the return value with leading 0s (zeros).
1471 * If places is not an integer, it is truncated.
1472 * If places is nonnumeric, HEX2OCT returns the #VALUE! error
1473 * value.
1474 * If places is negative, HEX2OCT returns the #NUM! error value.
1475 * @return string
1476 */
1477 public static function HEXTOOCT($x, $places=null) {
1478 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1479 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1480
1481 if (is_bool($x)) {
1482 return PHPExcel_Calculation_Functions::VALUE();
1483 }
1484 $x = (string) $x;
1485 if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) {
1486 return PHPExcel_Calculation_Functions::NaN();
1487 }
1488 $octVal = decoct(hexdec($x));
1489
1490 return self::_nbrConversionFormat($octVal,$places);
1491 } // function HEXTOOCT()
1492
1493
1494 /**
1495 * OCTTOBIN
1496 *
1497 * Return an octal value as binary.
1498 *
1499 * Excel Function:
1500 * OCT2BIN(x[,places])
1501 *
1502 * @access public
1503 * @category Engineering Functions
1504 * @param string $x The octal number you want to convert. Number may not
1505 * contain more than 10 characters. The most significant
1506 * bit of number is the sign bit. The remaining 29 bits
1507 * are magnitude bits. Negative numbers are represented
1508 * using two's-complement notation.
1509 * If number is negative, OCT2BIN ignores places and returns
1510 * a 10-character binary number.
1511 * If number is negative, it cannot be less than 7777777000,
1512 * and if number is positive, it cannot be greater than 777.
1513 * If number is not a valid octal number, OCT2BIN returns
1514 * the #NUM! error value.
1515 * If OCT2BIN requires more than places characters, it
1516 * returns the #NUM! error value.
1517 * @param integer $places The number of characters to use. If places is omitted,
1518 * OCT2BIN uses the minimum number of characters necessary.
1519 * Places is useful for padding the return value with
1520 * leading 0s (zeros).
1521 * If places is not an integer, it is truncated.
1522 * If places is nonnumeric, OCT2BIN returns the #VALUE!
1523 * error value.
1524 * If places is negative, OCT2BIN returns the #NUM! error
1525 * value.
1526 * @return string
1527 */
1528 public static function OCTTOBIN($x, $places=null) {
1529 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1530 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1531
1532 if (is_bool($x)) {
1533 return PHPExcel_Calculation_Functions::VALUE();
1534 }
1535 $x = (string) $x;
1536 if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) {
1537 return PHPExcel_Calculation_Functions::NaN();
1538 }
1539 $r = decbin(octdec($x));
1540
1541 return self::_nbrConversionFormat($r,$places);
1542 } // function OCTTOBIN()
1543
1544
1545 /**
1546 * OCTTODEC
1547 *
1548 * Return an octal value as decimal.
1549 *
1550 * Excel Function:
1551 * OCT2DEC(x)
1552 *
1553 * @access public
1554 * @category Engineering Functions
1555 * @param string $x The octal number you want to convert. Number may not contain
1556 * more than 10 octal characters (30 bits). The most significant
1557 * bit of number is the sign bit. The remaining 29 bits are
1558 * magnitude bits. Negative numbers are represented using
1559 * two's-complement notation.
1560 * If number is not a valid octal number, OCT2DEC returns the
1561 * #NUM! error value.
1562 * @return string
1563 */
1564 public static function OCTTODEC($x) {
1565 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1566
1567 if (is_bool($x)) {
1568 return PHPExcel_Calculation_Functions::VALUE();
1569 }
1570 $x = (string) $x;
1571 if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) {
1572 return PHPExcel_Calculation_Functions::NaN();
1573 }
1574 return octdec($x);
1575 } // function OCTTODEC()
1576
1577
1578 /**
1579 * OCTTOHEX
1580 *
1581 * Return an octal value as hex.
1582 *
1583 * Excel Function:
1584 * OCT2HEX(x[,places])
1585 *
1586 * @access public
1587 * @category Engineering Functions
1588 * @param string $x The octal number you want to convert. Number may not contain
1589 * more than 10 octal characters (30 bits). The most significant
1590 * bit of number is the sign bit. The remaining 29 bits are
1591 * magnitude bits. Negative numbers are represented using
1592 * two's-complement notation.
1593 * If number is negative, OCT2HEX ignores places and returns a
1594 * 10-character hexadecimal number.
1595 * If number is not a valid octal number, OCT2HEX returns the
1596 * #NUM! error value.
1597 * If OCT2HEX requires more than places characters, it returns
1598 * the #NUM! error value.
1599 * @param integer $places The number of characters to use. If places is omitted, OCT2HEX
1600 * uses the minimum number of characters necessary. Places is useful
1601 * for padding the return value with leading 0s (zeros).
1602 * If places is not an integer, it is truncated.
1603 * If places is nonnumeric, OCT2HEX returns the #VALUE! error value.
1604 * If places is negative, OCT2HEX returns the #NUM! error value.
1605 * @return string
1606 */
1607 public static function OCTTOHEX($x, $places=null) {
1608 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
1609 $places = PHPExcel_Calculation_Functions::flattenSingleValue($places);
1610
1611 if (is_bool($x)) {
1612 return PHPExcel_Calculation_Functions::VALUE();
1613 }
1614 $x = (string) $x;
1615 if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) {
1616 return PHPExcel_Calculation_Functions::NaN();
1617 }
1618 $hexVal = strtoupper(dechex(octdec($x)));
1619
1620 return self::_nbrConversionFormat($hexVal,$places);
1621 } // function OCTTOHEX()
1622
1623
1624 /**
1625 * COMPLEX
1626 *
1627 * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj.
1628 *
1629 * Excel Function:
1630 * COMPLEX(realNumber,imaginary[,places])
1631 *
1632 * @access public
1633 * @category Engineering Functions
1634 * @param float $realNumber The real coefficient of the complex number.
1635 * @param float $imaginary The imaginary coefficient of the complex number.
1636 * @param string $suffix The suffix for the imaginary component of the complex number.
1637 * If omitted, the suffix is assumed to be "i".
1638 * @return string
1639 */
1640 public static function COMPLEX($realNumber=0.0, $imaginary=0.0, $suffix='i') {
1641 $realNumber = (is_null($realNumber)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($realNumber);
1642 $imaginary = (is_null($imaginary)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($imaginary);
1643 $suffix = (is_null($suffix)) ? 'i' : PHPExcel_Calculation_Functions::flattenSingleValue($suffix);
1644
1645 if (((is_numeric($realNumber)) && (is_numeric($imaginary))) &&
1646 (($suffix == 'i') || ($suffix == 'j') || ($suffix == ''))) {
1647 $realNumber = (float) $realNumber;
1648 $imaginary = (float) $imaginary;
1649
1650 if ($suffix == '') $suffix = 'i';
1651 if ($realNumber == 0.0) {
1652 if ($imaginary == 0.0) {
1653 return (string) '0';
1654 } elseif ($imaginary == 1.0) {
1655 return (string) $suffix;
1656 } elseif ($imaginary == -1.0) {
1657 return (string) '-'.$suffix;
1658 }
1659 return (string) $imaginary.$suffix;
1660 } elseif ($imaginary == 0.0) {
1661 return (string) $realNumber;
1662 } elseif ($imaginary == 1.0) {
1663 return (string) $realNumber.'+'.$suffix;
1664 } elseif ($imaginary == -1.0) {
1665 return (string) $realNumber.'-'.$suffix;
1666 }
1667 if ($imaginary > 0) { $imaginary = (string) '+'.$imaginary; }
1668 return (string) $realNumber.$imaginary.$suffix;
1669 }
1670
1671 return PHPExcel_Calculation_Functions::VALUE();
1672 } // function COMPLEX()
1673
1674
1675 /**
1676 * IMAGINARY
1677 *
1678 * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format.
1679 *
1680 * Excel Function:
1681 * IMAGINARY(complexNumber)
1682 *
1683 * @access public
1684 * @category Engineering Functions
1685 * @param string $complexNumber The complex number for which you want the imaginary
1686 * coefficient.
1687 * @return float
1688 */
1689 public static function IMAGINARY($complexNumber) {
1690 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1691
1692 $parsedComplex = self::_parseComplex($complexNumber);
1693 return $parsedComplex['imaginary'];
1694 } // function IMAGINARY()
1695
1696
1697 /**
1698 * IMREAL
1699 *
1700 * Returns the real coefficient of a complex number in x + yi or x + yj text format.
1701 *
1702 * Excel Function:
1703 * IMREAL(complexNumber)
1704 *
1705 * @access public
1706 * @category Engineering Functions
1707 * @param string $complexNumber The complex number for which you want the real coefficient.
1708 * @return float
1709 */
1710 public static function IMREAL($complexNumber) {
1711 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1712
1713 $parsedComplex = self::_parseComplex($complexNumber);
1714 return $parsedComplex['real'];
1715 } // function IMREAL()
1716
1717
1718 /**
1719 * IMABS
1720 *
1721 * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format.
1722 *
1723 * Excel Function:
1724 * IMABS(complexNumber)
1725 *
1726 * @param string $complexNumber The complex number for which you want the absolute value.
1727 * @return float
1728 */
1729 public static function IMABS($complexNumber) {
1730 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1731
1732 $parsedComplex = self::_parseComplex($complexNumber);
1733
1734 return sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']));
1735 } // function IMABS()
1736
1737
1738 /**
1739 * IMARGUMENT
1740 *
1741 * Returns the argument theta of a complex number, i.e. the angle in radians from the real
1742 * axis to the representation of the number in polar coordinates.
1743 *
1744 * Excel Function:
1745 * IMARGUMENT(complexNumber)
1746 *
1747 * @param string $complexNumber The complex number for which you want the argument theta.
1748 * @return float
1749 */
1750 public static function IMARGUMENT($complexNumber) {
1751 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1752
1753 $parsedComplex = self::_parseComplex($complexNumber);
1754
1755 if ($parsedComplex['real'] == 0.0) {
1756 if ($parsedComplex['imaginary'] == 0.0) {
1757 return 0.0;
1758 } elseif($parsedComplex['imaginary'] < 0.0) {
1759 return M_PI / -2;
1760 } else {
1761 return M_PI / 2;
1762 }
1763 } elseif ($parsedComplex['real'] > 0.0) {
1764 return atan($parsedComplex['imaginary'] / $parsedComplex['real']);
1765 } elseif ($parsedComplex['imaginary'] < 0.0) {
1766 return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real'])));
1767 } else {
1768 return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real']));
1769 }
1770 } // function IMARGUMENT()
1771
1772
1773 /**
1774 * IMCONJUGATE
1775 *
1776 * Returns the complex conjugate of a complex number in x + yi or x + yj text format.
1777 *
1778 * Excel Function:
1779 * IMCONJUGATE(complexNumber)
1780 *
1781 * @param string $complexNumber The complex number for which you want the conjugate.
1782 * @return string
1783 */
1784 public static function IMCONJUGATE($complexNumber) {
1785 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1786
1787 $parsedComplex = self::_parseComplex($complexNumber);
1788
1789 if ($parsedComplex['imaginary'] == 0.0) {
1790 return $parsedComplex['real'];
1791 } else {
1792 return self::_cleanComplex( self::COMPLEX( $parsedComplex['real'],
1793 0 - $parsedComplex['imaginary'],
1794 $parsedComplex['suffix']
1795 )
1796 );
1797 }
1798 } // function IMCONJUGATE()
1799
1800
1801 /**
1802 * IMCOS
1803 *
1804 * Returns the cosine of a complex number in x + yi or x + yj text format.
1805 *
1806 * Excel Function:
1807 * IMCOS(complexNumber)
1808 *
1809 * @param string $complexNumber The complex number for which you want the cosine.
1810 * @return string|float
1811 */
1812 public static function IMCOS($complexNumber) {
1813 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1814
1815 $parsedComplex = self::_parseComplex($complexNumber);
1816
1817 if ($parsedComplex['imaginary'] == 0.0) {
1818 return cos($parsedComplex['real']);
1819 } else {
1820 return self::IMCONJUGATE(self::COMPLEX(cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']),sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix']));
1821 }
1822 } // function IMCOS()
1823
1824
1825 /**
1826 * IMSIN
1827 *
1828 * Returns the sine of a complex number in x + yi or x + yj text format.
1829 *
1830 * Excel Function:
1831 * IMSIN(complexNumber)
1832 *
1833 * @param string $complexNumber The complex number for which you want the sine.
1834 * @return string|float
1835 */
1836 public static function IMSIN($complexNumber) {
1837 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1838
1839 $parsedComplex = self::_parseComplex($complexNumber);
1840
1841 if ($parsedComplex['imaginary'] == 0.0) {
1842 return sin($parsedComplex['real']);
1843 } else {
1844 return self::COMPLEX(sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']),cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix']);
1845 }
1846 } // function IMSIN()
1847
1848
1849 /**
1850 * IMSQRT
1851 *
1852 * Returns the square root of a complex number in x + yi or x + yj text format.
1853 *
1854 * Excel Function:
1855 * IMSQRT(complexNumber)
1856 *
1857 * @param string $complexNumber The complex number for which you want the square root.
1858 * @return string
1859 */
1860 public static function IMSQRT($complexNumber) {
1861 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1862
1863 $parsedComplex = self::_parseComplex($complexNumber);
1864
1865 $theta = self::IMARGUMENT($complexNumber);
1866 $d1 = cos($theta / 2);
1867 $d2 = sin($theta / 2);
1868 $r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));
1869
1870 if ($parsedComplex['suffix'] == '') {
1871 return self::COMPLEX($d1 * $r,$d2 * $r);
1872 } else {
1873 return self::COMPLEX($d1 * $r,$d2 * $r,$parsedComplex['suffix']);
1874 }
1875 } // function IMSQRT()
1876
1877
1878 /**
1879 * IMLN
1880 *
1881 * Returns the natural logarithm of a complex number in x + yi or x + yj text format.
1882 *
1883 * Excel Function:
1884 * IMLN(complexNumber)
1885 *
1886 * @param string $complexNumber The complex number for which you want the natural logarithm.
1887 * @return string
1888 */
1889 public static function IMLN($complexNumber) {
1890 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1891
1892 $parsedComplex = self::_parseComplex($complexNumber);
1893
1894 if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
1895 return PHPExcel_Calculation_Functions::NaN();
1896 }
1897
1898 $logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));
1899 $t = self::IMARGUMENT($complexNumber);
1900
1901 if ($parsedComplex['suffix'] == '') {
1902 return self::COMPLEX($logR,$t);
1903 } else {
1904 return self::COMPLEX($logR,$t,$parsedComplex['suffix']);
1905 }
1906 } // function IMLN()
1907
1908
1909 /**
1910 * IMLOG10
1911 *
1912 * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format.
1913 *
1914 * Excel Function:
1915 * IMLOG10(complexNumber)
1916 *
1917 * @param string $complexNumber The complex number for which you want the common logarithm.
1918 * @return string
1919 */
1920 public static function IMLOG10($complexNumber) {
1921 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1922
1923 $parsedComplex = self::_parseComplex($complexNumber);
1924
1925 if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
1926 return PHPExcel_Calculation_Functions::NaN();
1927 } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
1928 return log10($parsedComplex['real']);
1929 }
1930
1931 return self::IMPRODUCT(log10(EULER),self::IMLN($complexNumber));
1932 } // function IMLOG10()
1933
1934
1935 /**
1936 * IMLOG2
1937 *
1938 * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format.
1939 *
1940 * Excel Function:
1941 * IMLOG2(complexNumber)
1942 *
1943 * @param string $complexNumber The complex number for which you want the base-2 logarithm.
1944 * @return string
1945 */
1946 public static function IMLOG2($complexNumber) {
1947 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1948
1949 $parsedComplex = self::_parseComplex($complexNumber);
1950
1951 if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
1952 return PHPExcel_Calculation_Functions::NaN();
1953 } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
1954 return log($parsedComplex['real'],2);
1955 }
1956
1957 return self::IMPRODUCT(log(EULER,2),self::IMLN($complexNumber));
1958 } // function IMLOG2()
1959
1960
1961 /**
1962 * IMEXP
1963 *
1964 * Returns the exponential of a complex number in x + yi or x + yj text format.
1965 *
1966 * Excel Function:
1967 * IMEXP(complexNumber)
1968 *
1969 * @param string $complexNumber The complex number for which you want the exponential.
1970 * @return string
1971 */
1972 public static function IMEXP($complexNumber) {
1973 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
1974
1975 $parsedComplex = self::_parseComplex($complexNumber);
1976
1977 if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {
1978 return '1';
1979 }
1980
1981 $e = exp($parsedComplex['real']);
1982 $eX = $e * cos($parsedComplex['imaginary']);
1983 $eY = $e * sin($parsedComplex['imaginary']);
1984
1985 if ($parsedComplex['suffix'] == '') {
1986 return self::COMPLEX($eX,$eY);
1987 } else {
1988 return self::COMPLEX($eX,$eY,$parsedComplex['suffix']);
1989 }
1990 } // function IMEXP()
1991
1992
1993 /**
1994 * IMPOWER
1995 *
1996 * Returns a complex number in x + yi or x + yj text format raised to a power.
1997 *
1998 * Excel Function:
1999 * IMPOWER(complexNumber,realNumber)
2000 *
2001 * @param string $complexNumber The complex number you want to raise to a power.
2002 * @param float $realNumber The power to which you want to raise the complex number.
2003 * @return string
2004 */
2005 public static function IMPOWER($complexNumber,$realNumber) {
2006 $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);
2007 $realNumber = PHPExcel_Calculation_Functions::flattenSingleValue($realNumber);
2008
2009 if (!is_numeric($realNumber)) {
2010 return PHPExcel_Calculation_Functions::VALUE();
2011 }
2012
2013 $parsedComplex = self::_parseComplex($complexNumber);
2014
2015 $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']));
2016 $rPower = pow($r,$realNumber);
2017 $theta = self::IMARGUMENT($complexNumber) * $realNumber;
2018 if ($theta == 0) {
2019 return 1;
2020 } elseif ($parsedComplex['imaginary'] == 0.0) {
2021 return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']);
2022 } else {
2023 return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']);
2024 }
2025 } // function IMPOWER()
2026
2027
2028 /**
2029 * IMDIV
2030 *
2031 * Returns the quotient of two complex numbers in x + yi or x + yj text format.
2032 *
2033 * Excel Function:
2034 * IMDIV(complexDividend,complexDivisor)
2035 *
2036 * @param string $complexDividend The complex numerator or dividend.
2037 * @param string $complexDivisor The complex denominator or divisor.
2038 * @return string
2039 */
2040 public static function IMDIV($complexDividend,$complexDivisor) {
2041 $complexDividend = PHPExcel_Calculation_Functions::flattenSingleValue($complexDividend);
2042 $complexDivisor = PHPExcel_Calculation_Functions::flattenSingleValue($complexDivisor);
2043
2044 $parsedComplexDividend = self::_parseComplex($complexDividend);
2045 $parsedComplexDivisor = self::_parseComplex($complexDivisor);
2046
2047 if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') &&
2048 ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])) {
2049 return PHPExcel_Calculation_Functions::NaN();
2050 }
2051 if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) {
2052 $parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix'];
2053 }
2054
2055 $d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']);
2056 $d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']);
2057 $d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']);
2058
2059 $r = $d1/$d3;
2060 $i = $d2/$d3;
2061
2062 if ($i > 0.0) {
2063 return self::_cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']);
2064 } elseif ($i < 0.0) {
2065 return self::_cleanComplex($r.$i.$parsedComplexDivisor['suffix']);
2066 } else {
2067 return $r;
2068 }
2069 } // function IMDIV()
2070
2071
2072 /**
2073 * IMSUB
2074 *
2075 * Returns the difference of two complex numbers in x + yi or x + yj text format.
2076 *
2077 * Excel Function:
2078 * IMSUB(complexNumber1,complexNumber2)
2079 *
2080 * @param string $complexNumber1 The complex number from which to subtract complexNumber2.
2081 * @param string $complexNumber2 The complex number to subtract from complexNumber1.
2082 * @return string
2083 */
2084 public static function IMSUB($complexNumber1,$complexNumber2) {
2085 $complexNumber1 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber1);
2086 $complexNumber2 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber2);
2087
2088 $parsedComplex1 = self::_parseComplex($complexNumber1);
2089 $parsedComplex2 = self::_parseComplex($complexNumber2);
2090
2091 if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) &&
2092 ($parsedComplex1['suffix'] != $parsedComplex2['suffix'])) {
2093 return PHPExcel_Calculation_Functions::NaN();
2094 } elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) {
2095 $parsedComplex1['suffix'] = $parsedComplex2['suffix'];
2096 }
2097
2098 $d1 = $parsedComplex1['real'] - $parsedComplex2['real'];
2099 $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary'];
2100
2101 return self::COMPLEX($d1,$d2,$parsedComplex1['suffix']);
2102 } // function IMSUB()
2103
2104
2105 /**
2106 * IMSUM
2107 *
2108 * Returns the sum of two or more complex numbers in x + yi or x + yj text format.
2109 *
2110 * Excel Function:
2111 * IMSUM(complexNumber[,complexNumber[,...]])
2112 *
2113 * @param string $complexNumber,... Series of complex numbers to add
2114 * @return string
2115 */
2116 public static function IMSUM() {
2117 // Return value
2118 $returnValue = self::_parseComplex('0');
2119 $activeSuffix = '';
2120
2121 // Loop through the arguments
2122 $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());
2123 foreach ($aArgs as $arg) {
2124 $parsedComplex = self::_parseComplex($arg);
2125
2126 if ($activeSuffix == '') {
2127 $activeSuffix = $parsedComplex['suffix'];
2128 } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) {
2129 return PHPExcel_Calculation_Functions::VALUE();
2130 }
2131
2132 $returnValue['real'] += $parsedComplex['real'];
2133 $returnValue['imaginary'] += $parsedComplex['imaginary'];
2134 }
2135
2136 if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; }
2137 return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix);
2138 } // function IMSUM()
2139
2140
2141 /**
2142 * IMPRODUCT
2143 *
2144 * Returns the product of two or more complex numbers in x + yi or x + yj text format.
2145 *
2146 * Excel Function:
2147 * IMPRODUCT(complexNumber[,complexNumber[,...]])
2148 *
2149 * @param string $complexNumber,... Series of complex numbers to multiply
2150 * @return string
2151 */
2152 public static function IMPRODUCT() {
2153 // Return value
2154 $returnValue = self::_parseComplex('1');
2155 $activeSuffix = '';
2156
2157 // Loop through the arguments
2158 $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());
2159 foreach ($aArgs as $arg) {
2160 $parsedComplex = self::_parseComplex($arg);
2161
2162 $workValue = $returnValue;
2163 if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) {
2164 $activeSuffix = $parsedComplex['suffix'];
2165 } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) {
2166 return PHPExcel_Calculation_Functions::NaN();
2167 }
2168 $returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']);
2169 $returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']);
2170 }
2171
2172 if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; }
2173 return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix);
2174 } // function IMPRODUCT()
2175
2176
2177 /**
2178 * DELTA
2179 *
2180 * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise.
2181 * Use this function to filter a set of values. For example, by summing several DELTA
2182 * functions you calculate the count of equal pairs. This function is also known as the
2183 * Kronecker Delta function.
2184 *
2185 * Excel Function:
2186 * DELTA(a[,b])
2187 *
2188 * @param float $a The first number.
2189 * @param float $b The second number. If omitted, b is assumed to be zero.
2190 * @return int
2191 */
2192 public static function DELTA($a, $b=0) {
2193 $a = PHPExcel_Calculation_Functions::flattenSingleValue($a);
2194 $b = PHPExcel_Calculation_Functions::flattenSingleValue($b);
2195
2196 return (int) ($a == $b);
2197 } // function DELTA()
2198
2199
2200 /**
2201 * GESTEP
2202 *
2203 * Excel Function:
2204 * GESTEP(number[,step])
2205 *
2206 * Returns 1 if number >= step; returns 0 (zero) otherwise
2207 * Use this function to filter a set of values. For example, by summing several GESTEP
2208 * functions you calculate the count of values that exceed a threshold.
2209 *
2210 * @param float $number The value to test against step.
2211 * @param float $step The threshold value.
2212 * If you omit a value for step, GESTEP uses zero.
2213 * @return int
2214 */
2215 public static function GESTEP($number, $step=0) {
2216 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number);
2217 $step = PHPExcel_Calculation_Functions::flattenSingleValue($step);
2218
2219 return (int) ($number >= $step);
2220 } // function GESTEP()
2221
2222
2223 //
2224 // Private method to calculate the erf value
2225 //
2226 private static $_two_sqrtpi = 1.128379167095512574;
2227
2228 public static function _erfVal($x) {
2229 if (abs($x) > 2.2) {
2230 return 1 - self::_erfcVal($x);
2231 }
2232 $sum = $term = $x;
2233 $xsqr = ($x * $x);
2234 $j = 1;
2235 do {
2236 $term *= $xsqr / $j;
2237 $sum -= $term / (2 * $j + 1);
2238 ++$j;
2239 $term *= $xsqr / $j;
2240 $sum += $term / (2 * $j + 1);
2241 ++$j;
2242 if ($sum == 0.0) {
2243 break;
2244 }
2245 } while (abs($term / $sum) > PRECISION);
2246 return self::$_two_sqrtpi * $sum;
2247 } // function _erfVal()
2248
2249
2250 /**
2251 * ERF
2252 *
2253 * Returns the error function integrated between the lower and upper bound arguments.
2254 *
2255 * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments,
2256 * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was
2257 * improved, so that it can now calculate the function for both positive and negative ranges.
2258 * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments.
2259 *
2260 * Excel Function:
2261 * ERF(lower[,upper])
2262 *
2263 * @param float $lower lower bound for integrating ERF
2264 * @param float $upper upper bound for integrating ERF.
2265 * If omitted, ERF integrates between zero and lower_limit
2266 * @return float
2267 */
2268 public static function ERF($lower, $upper = NULL) {
2269 $lower = PHPExcel_Calculation_Functions::flattenSingleValue($lower);
2270 $upper = PHPExcel_Calculation_Functions::flattenSingleValue($upper);
2271
2272 if (is_numeric($lower)) {
2273 if (is_null($upper)) {
2274 return self::_erfVal($lower);
2275 }
2276 if (is_numeric($upper)) {
2277 return self::_erfVal($upper) - self::_erfVal($lower);
2278 }
2279 }
2280 return PHPExcel_Calculation_Functions::VALUE();
2281 } // function ERF()
2282
2283
2284 //
2285 // Private method to calculate the erfc value
2286 //
2287 private static $_one_sqrtpi = 0.564189583547756287;
2288
2289 private static function _erfcVal($x) {
2290 if (abs($x) < 2.2) {
2291 return 1 - self::_erfVal($x);
2292 }
2293 if ($x < 0) {
2294 return 2 - self::ERFC(-$x);
2295 }
2296 $a = $n = 1;
2297 $b = $c = $x;
2298 $d = ($x * $x) + 0.5;
2299 $q1 = $q2 = $b / $d;
2300 $t = 0;
2301 do {
2302 $t = $a * $n + $b * $x;
2303 $a = $b;
2304 $b = $t;
2305 $t = $c * $n + $d * $x;
2306 $c = $d;
2307 $d = $t;
2308 $n += 0.5;
2309 $q1 = $q2;
2310 $q2 = $b / $d;
2311 } while ((abs($q1 - $q2) / $q2) > PRECISION);
2312 return self::$_one_sqrtpi * exp(-$x * $x) * $q2;
2313 } // function _erfcVal()
2314
2315
2316 /**
2317 * ERFC
2318 *
2319 * Returns the complementary ERF function integrated between x and infinity
2320 *
2321 * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument,
2322 * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was
2323 * improved, so that it can now calculate the function for both positive and negative x values.
2324 * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments.
2325 *
2326 * Excel Function:
2327 * ERFC(x)
2328 *
2329 * @param float $x The lower bound for integrating ERFC
2330 * @return float
2331 */
2332 public static function ERFC($x) {
2333 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x);
2334
2335 if (is_numeric($x)) {
2336 return self::_erfcVal($x);
2337 }
2338 return PHPExcel_Calculation_Functions::VALUE();
2339 } // function ERFC()
2340
2341
2342 /**
2343 * getConversionGroups
2344 * Returns a list of the different conversion groups for UOM conversions
2345 *
2346 * @return array
2347 */
2348 public static function getConversionGroups() {
2349 $conversionGroups = array();
2350 foreach(self::$_conversionUnits as $conversionUnit) {
2351 $conversionGroups[] = $conversionUnit['Group'];
2352 }
2353 return array_merge(array_unique($conversionGroups));
2354 } // function getConversionGroups()
2355
2356
2357 /**
2358 * getConversionGroupUnits
2359 * Returns an array of units of measure, for a specified conversion group, or for all groups
2360 *
2361 * @param string $group The group whose units of measure you want to retrieve
2362 * @return array
2363 */
2364 public static function getConversionGroupUnits($group = NULL) {
2365 $conversionGroups = array();
2366 foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) {
2367 if ((is_null($group)) || ($conversionGroup['Group'] == $group)) {
2368 $conversionGroups[$conversionGroup['Group']][] = $conversionUnit;
2369 }
2370 }
2371 return $conversionGroups;
2372 } // function getConversionGroupUnits()
2373
2374
2375 /**
2376 * getConversionGroupUnitDetails
2377 *
2378 * @param string $group The group whose units of measure you want to retrieve
2379 * @return array
2380 */
2381 public static function getConversionGroupUnitDetails($group = NULL) {
2382 $conversionGroups = array();
2383 foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) {
2384 if ((is_null($group)) || ($conversionGroup['Group'] == $group)) {
2385 $conversionGroups[$conversionGroup['Group']][] = array( 'unit' => $conversionUnit,
2386 'description' => $conversionGroup['Unit Name']
2387 );
2388 }
2389 }
2390 return $conversionGroups;
2391 } // function getConversionGroupUnitDetails()
2392
2393
2394 /**
2395 * getConversionMultipliers
2396 * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM()
2397 *
2398 * @return array of mixed
2399 */
2400 public static function getConversionMultipliers() {
2401 return self::$_conversionMultipliers;
2402 } // function getConversionGroups()
2403
2404
2405 /**
2406 * CONVERTUOM
2407 *
2408 * Converts a number from one measurement system to another.
2409 * For example, CONVERT can translate a table of distances in miles to a table of distances
2410 * in kilometers.
2411 *
2412 * Excel Function:
2413 * CONVERT(value,fromUOM,toUOM)
2414 *
2415 * @param float $value The value in fromUOM to convert.
2416 * @param string $fromUOM The units for value.
2417 * @param string $toUOM The units for the result.
2418 *
2419 * @return float
2420 */
2421 public static function CONVERTUOM($value, $fromUOM, $toUOM) {
2422 $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
2423 $fromUOM = PHPExcel_Calculation_Functions::flattenSingleValue($fromUOM);
2424 $toUOM = PHPExcel_Calculation_Functions::flattenSingleValue($toUOM);
2425
2426 if (!is_numeric($value)) {
2427 return PHPExcel_Calculation_Functions::VALUE();
2428 }
2429 $fromMultiplier = 1.0;
2430 if (isset(self::$_conversionUnits[$fromUOM])) {
2431 $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group'];
2432 } else {
2433 $fromMultiplier = substr($fromUOM,0,1);
2434 $fromUOM = substr($fromUOM,1);
2435 if (isset(self::$_conversionMultipliers[$fromMultiplier])) {
2436 $fromMultiplier = self::$_conversionMultipliers[$fromMultiplier]['multiplier'];
2437 } else {
2438 return PHPExcel_Calculation_Functions::NA();
2439 }
2440 if ((isset(self::$_conversionUnits[$fromUOM])) && (self::$_conversionUnits[$fromUOM]['AllowPrefix'])) {
2441 $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group'];
2442 } else {
2443 return PHPExcel_Calculation_Functions::NA();
2444 }
2445 }
2446 $value *= $fromMultiplier;
2447
2448 $toMultiplier = 1.0;
2449 if (isset(self::$_conversionUnits[$toUOM])) {
2450 $unitGroup2 = self::$_conversionUnits[$toUOM]['Group'];
2451 } else {
2452 $toMultiplier = substr($toUOM,0,1);
2453 $toUOM = substr($toUOM,1);
2454 if (isset(self::$_conversionMultipliers[$toMultiplier])) {
2455 $toMultiplier = self::$_conversionMultipliers[$toMultiplier]['multiplier'];
2456 } else {
2457 return PHPExcel_Calculation_Functions::NA();
2458 }
2459 if ((isset(self::$_conversionUnits[$toUOM])) && (self::$_conversionUnits[$toUOM]['AllowPrefix'])) {
2460 $unitGroup2 = self::$_conversionUnits[$toUOM]['Group'];
2461 } else {
2462 return PHPExcel_Calculation_Functions::NA();
2463 }
2464 }
2465 if ($unitGroup1 != $unitGroup2) {
2466 return PHPExcel_Calculation_Functions::NA();
2467 }
2468
2469 if (($fromUOM == $toUOM) && ($fromMultiplier == $toMultiplier)) {
2470 // We've already factored $fromMultiplier into the value, so we need
2471 // to reverse it again
2472 return $value / $fromMultiplier;
2473 } elseif ($unitGroup1 == 'Temperature') {
2474 if (($fromUOM == 'F') || ($fromUOM == 'fah')) {
2475 if (($toUOM == 'F') || ($toUOM == 'fah')) {
2476 return $value;
2477 } else {
2478 $value = (($value - 32) / 1.8);
2479 if (($toUOM == 'K') || ($toUOM == 'kel')) {
2480 $value += 273.15;
2481 }
2482 return $value;
2483 }
2484 } elseif ((($fromUOM == 'K') || ($fromUOM == 'kel')) &&
2485 (($toUOM == 'K') || ($toUOM == 'kel'))) {
2486 return $value;
2487 } elseif ((($fromUOM == 'C') || ($fromUOM == 'cel')) &&
2488 (($toUOM == 'C') || ($toUOM == 'cel'))) {
2489 return $value;
2490 }
2491 if (($toUOM == 'F') || ($toUOM == 'fah')) {
2492 if (($fromUOM == 'K') || ($fromUOM == 'kel')) {
2493 $value -= 273.15;
2494 }
2495 return ($value * 1.8) + 32;
2496 }
2497 if (($toUOM == 'C') || ($toUOM == 'cel')) {
2498 return $value - 273.15;
2499 }
2500 return $value + 273.15;
2501 }
2502 return ($value * self::$_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier;
2503 } // function CONVERTUOM()
2504
2505 } // class PHPExcel_Calculation_Engineering
2506