Subversion Repositories eFlore/Applications.cel

Rev

Rev 2388 | Details | Compare with Previous | Last modification | View Log | RSS feed

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