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