PageRenderTime 64ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/common/libraries/plugin/phpexcel/PHPExcel/Calculation/Engineering.php

https://bitbucket.org/ywarnier/chamilo-dev
PHP | 2135 lines | 1527 code | 207 blank | 401 comment | 315 complexity | 73769569c2093f011fe8c270a1918df6 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2011 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 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version 1.7.6, 2011-02-27
  26. */
  27. /** PHPExcel root directory */
  28. if (! defined('PHPEXCEL_ROOT'))
  29. {
  30. /**
  31. * @ignore
  32. */
  33. define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
  34. require (PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
  35. }
  36. /** EULER */
  37. define('EULER', 2.71828182845904523536);
  38. /**
  39. * PHPExcel_Calculation_Engineering
  40. *
  41. * @category PHPExcel
  42. * @package PHPExcel_Calculation
  43. * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  44. */
  45. class PHPExcel_Calculation_Engineering
  46. {
  47. private static $_conversionUnits = array(
  48. 'g' => array('Group' => 'Mass', 'Unit Name' => 'Gram', 'AllowPrefix' => True),
  49. 'sg' => array('Group' => 'Mass', 'Unit Name' => 'Slug', 'AllowPrefix' => False),
  50. 'lbm' => array('Group' => 'Mass', 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => False),
  51. 'u' => array('Group' => 'Mass', 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => True),
  52. 'ozm' => array('Group' => 'Mass', 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => False),
  53. 'm' => array('Group' => 'Distance', 'Unit Name' => 'Meter', 'AllowPrefix' => True),
  54. 'mi' => array('Group' => 'Distance', 'Unit Name' => 'Statute mile', 'AllowPrefix' => False),
  55. 'Nmi' => array('Group' => 'Distance', 'Unit Name' => 'Nautical mile', 'AllowPrefix' => False),
  56. 'in' => array('Group' => 'Distance', 'Unit Name' => 'Inch', 'AllowPrefix' => False),
  57. 'ft' => array('Group' => 'Distance', 'Unit Name' => 'Foot', 'AllowPrefix' => False),
  58. 'yd' => array('Group' => 'Distance', 'Unit Name' => 'Yard', 'AllowPrefix' => False),
  59. 'ang' => array('Group' => 'Distance', 'Unit Name' => 'Angstrom', 'AllowPrefix' => True),
  60. 'Pica' => array('Group' => 'Distance', 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => False),
  61. 'yr' => array('Group' => 'Time', 'Unit Name' => 'Year', 'AllowPrefix' => False),
  62. 'day' => array('Group' => 'Time', 'Unit Name' => 'Day', 'AllowPrefix' => False),
  63. 'hr' => array('Group' => 'Time', 'Unit Name' => 'Hour', 'AllowPrefix' => False),
  64. 'mn' => array('Group' => 'Time', 'Unit Name' => 'Minute', 'AllowPrefix' => False),
  65. 'sec' => array('Group' => 'Time', 'Unit Name' => 'Second', 'AllowPrefix' => True),
  66. 'Pa' => array('Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True),
  67. 'p' => array('Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True),
  68. 'atm' => array('Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True),
  69. 'at' => array('Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True),
  70. 'mmHg' => array('Group' => 'Pressure', 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => True),
  71. 'N' => array('Group' => 'Force', 'Unit Name' => 'Newton', 'AllowPrefix' => True),
  72. 'dyn' => array('Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True),
  73. 'dy' => array('Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True),
  74. 'lbf' => array('Group' => 'Force', 'Unit Name' => 'Pound force', 'AllowPrefix' => False),
  75. 'J' => array('Group' => 'Energy', 'Unit Name' => 'Joule', 'AllowPrefix' => True),
  76. 'e' => array('Group' => 'Energy', 'Unit Name' => 'Erg', 'AllowPrefix' => True),
  77. 'c' => array('Group' => 'Energy', 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => True),
  78. 'cal' => array('Group' => 'Energy', 'Unit Name' => 'IT calorie', 'AllowPrefix' => True),
  79. 'eV' => array('Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True),
  80. 'ev' => array('Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True),
  81. 'HPh' => array('Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False),
  82. 'hh' => array('Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False),
  83. 'Wh' => array('Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True),
  84. 'wh' => array('Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True),
  85. 'flb' => array('Group' => 'Energy', 'Unit Name' => 'Foot-pound', 'AllowPrefix' => False),
  86. 'BTU' => array('Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False),
  87. 'btu' => array('Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False),
  88. 'HP' => array('Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False),
  89. 'h' => array('Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False),
  90. 'W' => array('Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True),
  91. 'w' => array('Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True),
  92. 'T' => array('Group' => 'Magnetism', 'Unit Name' => 'Tesla', 'AllowPrefix' => True),
  93. 'ga' => array('Group' => 'Magnetism', 'Unit Name' => 'Gauss', 'AllowPrefix' => True),
  94. 'C' => array('Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False),
  95. 'cel' => array('Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False),
  96. 'F' => array('Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False),
  97. 'fah' => array('Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False),
  98. 'K' => array('Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False),
  99. 'kel' => array('Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False),
  100. 'tsp' => array('Group' => 'Liquid', 'Unit Name' => 'Teaspoon', 'AllowPrefix' => False),
  101. 'tbs' => array('Group' => 'Liquid', 'Unit Name' => 'Tablespoon', 'AllowPrefix' => False),
  102. 'oz' => array('Group' => 'Liquid', 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => False),
  103. 'cup' => array('Group' => 'Liquid', 'Unit Name' => 'Cup', 'AllowPrefix' => False),
  104. 'pt' => array('Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False),
  105. 'us_pt' => array('Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False),
  106. 'uk_pt' => array('Group' => 'Liquid', 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => False),
  107. 'qt' => array('Group' => 'Liquid', 'Unit Name' => 'Quart', 'AllowPrefix' => False),
  108. 'gal' => array('Group' => 'Liquid', 'Unit Name' => 'Gallon', 'AllowPrefix' => False),
  109. 'l' => array('Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True),
  110. 'lt' => array('Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True));
  111. private static $_conversionMultipliers = array('Y' => array('multiplier' => 1E24, 'name' => 'yotta'),
  112. 'Z' => array('multiplier' => 1E21, 'name' => 'zetta'), 'E' => array('multiplier' => 1E18, 'name' => 'exa'),
  113. 'P' => array('multiplier' => 1E15, 'name' => 'peta'), 'T' => array('multiplier' => 1E12, 'name' => 'tera'),
  114. 'G' => array('multiplier' => 1E9, 'name' => 'giga'), 'M' => array('multiplier' => 1E6, 'name' => 'mega'),
  115. 'k' => array('multiplier' => 1E3, 'name' => 'kilo'), 'h' => array('multiplier' => 1E2, 'name' => 'hecto'),
  116. 'e' => array('multiplier' => 1E1, 'name' => 'deka'), 'd' => array('multiplier' => 1E-1, 'name' => 'deci'),
  117. 'c' => array('multiplier' => 1E-2, 'name' => 'centi'),
  118. 'm' => array('multiplier' => 1E-3, 'name' => 'milli'),
  119. 'u' => array('multiplier' => 1E-6, 'name' => 'micro'),
  120. 'n' => array('multiplier' => 1E-9, 'name' => 'nano'),
  121. 'p' => array('multiplier' => 1E-12, 'name' => 'pico'),
  122. 'f' => array('multiplier' => 1E-15, 'name' => 'femto'),
  123. 'a' => array('multiplier' => 1E-18, 'name' => 'atto'),
  124. 'z' => array('multiplier' => 1E-21, 'name' => 'zepto'),
  125. 'y' => array('multiplier' => 1E-24, 'name' => 'yocto'));
  126. private static $_unitConversions = array(
  127. 'Mass' => array(
  128. 'g' => array('g' => 1.0, 'sg' => 6.85220500053478E-05, 'lbm' => 2.20462291469134E-03,
  129. 'u' => 6.02217000000000E+23, 'ozm' => 3.52739718003627E-02),
  130. 'sg' => array('g' => 1.45938424189287E+04, 'sg' => 1.0, 'lbm' => 3.21739194101647E+01,
  131. 'u' => 8.78866000000000E+27, 'ozm' => 5.14782785944229E+02),
  132. 'lbm' => array('g' => 4.5359230974881148E+02, 'sg' => 3.10810749306493E-02, 'lbm' => 1.0,
  133. 'u' => 2.73161000000000E+26, 'ozm' => 1.60000023429410E+01),
  134. 'u' => array('g' => 1.66053100460465E-24, 'sg' => 1.13782988532950E-28,
  135. 'lbm' => 3.66084470330684E-27, 'u' => 1.0, 'ozm' => 5.85735238300524E-26),
  136. 'ozm' => array('g' => 2.83495152079732E+01, 'sg' => 1.94256689870811E-03,
  137. 'lbm' => 6.24999908478882E-02, 'u' => 1.70725600000000E+25, 'ozm' => 1.0)),
  138. 'Distance' => array(
  139. 'm' => array('m' => 1.0, 'mi' => 6.21371192237334E-04, 'Nmi' => 5.39956803455724E-04,
  140. 'in' => 3.93700787401575E+01, 'ft' => 3.28083989501312E+00, 'yd' => 1.09361329797891E+00,
  141. 'ang' => 1.00000000000000E+10, 'Pica' => 2.83464566929116E+03),
  142. 'mi' => array('m' => 1.60934400000000E+03, 'mi' => 1.0, 'Nmi' => 8.68976241900648E-01,
  143. 'in' => 6.33600000000000E+04, 'ft' => 5.28000000000000E+03, 'yd' => 1.76000000000000E+03,
  144. 'ang' => 1.60934400000000E+13, 'Pica' => 4.56191999999971E+06),
  145. 'Nmi' => array('m' => 1.85200000000000E+03, 'mi' => 1.15077944802354E+00, 'Nmi' => 1.0,
  146. 'in' => 7.29133858267717E+04, 'ft' => 6.07611548556430E+03, 'yd' => 2.02537182785694E+03,
  147. 'ang' => 1.85200000000000E+13, 'Pica' => 5.24976377952723E+06),
  148. 'in' => array('m' => 2.54000000000000E-02, 'mi' => 1.57828282828283E-05,
  149. 'Nmi' => 1.37149028077754E-05, 'in' => 1.0, 'ft' => 8.33333333333333E-02,
  150. 'yd' => 2.77777777686643E-02, 'ang' => 2.54000000000000E+08, 'Pica' => 7.19999999999955E+01),
  151. 'ft' => array('m' => 3.04800000000000E-01, 'mi' => 1.89393939393939E-04,
  152. 'Nmi' => 1.64578833693305E-04, 'in' => 1.20000000000000E+01, 'ft' => 1.0,
  153. 'yd' => 3.33333333223972E-01, 'ang' => 3.04800000000000E+09, 'Pica' => 8.63999999999946E+02),
  154. 'yd' => array('m' => 9.14400000300000E-01, 'mi' => 5.68181818368230E-04,
  155. 'Nmi' => 4.93736501241901E-04, 'in' => 3.60000000118110E+01, 'ft' => 3.00000000000000E+00,
  156. 'yd' => 1.0, 'ang' => 9.14400000300000E+09, 'Pica' => 2.59200000085023E+03),
  157. 'ang' => array('m' => 1.00000000000000E-10, 'mi' => 6.21371192237334E-14,
  158. 'Nmi' => 5.39956803455724E-14, 'in' => 3.93700787401575E-09, 'ft' => 3.28083989501312E-10,
  159. 'yd' => 1.09361329797891E-10, 'ang' => 1.0, 'Pica' => 2.83464566929116E-07),
  160. 'Pica' => array('m' => 3.52777777777800E-04, 'mi' => 2.19205948372629E-07,
  161. 'Nmi' => 1.90484761219114E-07, 'in' => 1.38888888888898E-02, 'ft' => 1.15740740740748E-03,
  162. 'yd' => 3.85802469009251E-04, 'ang' => 3.52777777777800E+06, 'Pica' => 1.0)),
  163. 'Time' => array(
  164. 'yr' => array('yr' => 1.0, 'day' => 365.25, 'hr' => 8766.0, 'mn' => 525960.0, 'sec' => 31557600.0),
  165. 'day' => array('yr' => 2.73785078713210E-03, 'day' => 1.0, 'hr' => 24.0, 'mn' => 1440.0,
  166. 'sec' => 86400.0),
  167. 'hr' => array('yr' => 1.14077116130504E-04, 'day' => 4.16666666666667E-02, 'hr' => 1.0,
  168. 'mn' => 60.0, 'sec' => 3600.0),
  169. 'mn' => array('yr' => 1.90128526884174E-06, 'day' => 6.94444444444444E-04,
  170. 'hr' => 1.66666666666667E-02, 'mn' => 1.0, 'sec' => 60.0),
  171. 'sec' => array('yr' => 3.16880878140289E-08, 'day' => 1.15740740740741E-05,
  172. 'hr' => 2.77777777777778E-04, 'mn' => 1.66666666666667E-02, 'sec' => 1.0)),
  173. 'Pressure' => array(
  174. 'Pa' => array('Pa' => 1.0, 'p' => 1.0, 'atm' => 9.86923299998193E-06, 'at' => 9.86923299998193E-06,
  175. 'mmHg' => 7.50061707998627E-03),
  176. 'p' => array('Pa' => 1.0, 'p' => 1.0, 'atm' => 9.86923299998193E-06, 'at' => 9.86923299998193E-06,
  177. 'mmHg' => 7.50061707998627E-03),
  178. 'atm' => array('Pa' => 1.01324996583000E+05, 'p' => 1.01324996583000E+05, 'atm' => 1.0,
  179. 'at' => 1.0, 'mmHg' => 760.0),
  180. 'at' => array('Pa' => 1.01324996583000E+05, 'p' => 1.01324996583000E+05, 'atm' => 1.0, 'at' => 1.0,
  181. 'mmHg' => 760.0),
  182. 'mmHg' => array('Pa' => 1.33322363925000E+02, 'p' => 1.33322363925000E+02,
  183. 'atm' => 1.31578947368421E-03, 'at' => 1.31578947368421E-03, 'mmHg' => 1.0)),
  184. 'Force' => array(
  185. 'N' => array('N' => 1.0, 'dyn' => 1.0E+5, 'dy' => 1.0E+5, 'lbf' => 2.24808923655339E-01),
  186. 'dyn' => array('N' => 1.0E-5, 'dyn' => 1.0, 'dy' => 1.0, 'lbf' => 2.24808923655339E-06),
  187. 'dy' => array('N' => 1.0E-5, 'dyn' => 1.0, 'dy' => 1.0, 'lbf' => 2.24808923655339E-06),
  188. 'lbf' => array('N' => 4.448222, 'dyn' => 4.448222E+5, 'dy' => 4.448222E+5, 'lbf' => 1.0)),
  189. 'Energy' => array(
  190. 'J' => array('J' => 1.0, 'e' => 9.99999519343231E+06, 'c' => 2.39006249473467E-01,
  191. 'cal' => 2.38846190642017E-01, 'eV' => 6.24145700000000E+18, 'ev' => 6.24145700000000E+18,
  192. 'HPh' => 3.72506430801000E-07, 'hh' => 3.72506430801000E-07, 'Wh' => 2.77777916238711E-04,
  193. 'wh' => 2.77777916238711E-04, 'flb' => 2.37304222192651E+01, 'BTU' => 9.47815067349015E-04,
  194. 'btu' => 9.47815067349015E-04),
  195. 'e' => array('J' => 1.00000048065700E-07, 'e' => 1.0, 'c' => 2.39006364353494E-08,
  196. 'cal' => 2.38846305445111E-08, 'eV' => 6.24146000000000E+11, 'ev' => 6.24146000000000E+11,
  197. 'HPh' => 3.72506609848824E-14, 'hh' => 3.72506609848824E-14, 'Wh' => 2.77778049754611E-11,
  198. 'wh' => 2.77778049754611E-11, 'flb' => 2.37304336254586E-06, 'BTU' => 9.47815522922962E-11,
  199. 'btu' => 9.47815522922962E-11),
  200. 'c' => array('J' => 4.18399101363672E+00, 'e' => 4.18398900257312E+07, 'c' => 1.0,
  201. 'cal' => 9.99330315287563E-01, 'eV' => 2.61142000000000E+19, 'ev' => 2.61142000000000E+19,
  202. 'HPh' => 1.55856355899327E-06, 'hh' => 1.55856355899327E-06, 'Wh' => 1.16222030532950E-03,
  203. 'wh' => 1.16222030532950E-03, 'flb' => 9.92878733152102E+01, 'BTU' => 3.96564972437776E-03,
  204. 'btu' => 3.96564972437776E-03),
  205. 'cal' => array('J' => 4.18679484613929E+00, 'e' => 4.18679283372801E+07,
  206. 'c' => 1.00067013349059E+00, 'cal' => 1.0, 'eV' => 2.61317000000000E+19,
  207. 'ev' => 2.61317000000000E+19, 'HPh' => 1.55960800463137E-06, 'hh' => 1.55960800463137E-06,
  208. 'Wh' => 1.16299914807955E-03, 'wh' => 1.16299914807955E-03, 'flb' => 9.93544094443283E+01,
  209. 'BTU' => 3.96830723907002E-03, 'btu' => 3.96830723907002E-03),
  210. 'eV' => array('J' => 1.60219000146921E-19, 'e' => 1.60218923136574E-12,
  211. 'c' => 3.82933423195043E-20, 'cal' => 3.82676978535648E-20, 'eV' => 1.0, 'ev' => 1.0,
  212. 'HPh' => 5.96826078912344E-26, 'hh' => 5.96826078912344E-26, 'Wh' => 4.45053000026614E-23,
  213. 'wh' => 4.45053000026614E-23, 'flb' => 3.80206452103492E-18, 'BTU' => 1.51857982414846E-22,
  214. 'btu' => 1.51857982414846E-22),
  215. 'ev' => array('J' => 1.60219000146921E-19, 'e' => 1.60218923136574E-12,
  216. 'c' => 3.82933423195043E-20, 'cal' => 3.82676978535648E-20, 'eV' => 1.0, 'ev' => 1.0,
  217. 'HPh' => 5.96826078912344E-26, 'hh' => 5.96826078912344E-26, 'Wh' => 4.45053000026614E-23,
  218. 'wh' => 4.45053000026614E-23, 'flb' => 3.80206452103492E-18, 'BTU' => 1.51857982414846E-22,
  219. 'btu' => 1.51857982414846E-22),
  220. 'HPh' => array('J' => 2.68451741316170E+06, 'e' => 2.68451612283024E+13,
  221. 'c' => 6.41616438565991E+05, 'cal' => 6.41186757845835E+05, 'eV' => 1.67553000000000E+25,
  222. 'ev' => 1.67553000000000E+25, 'HPh' => 1.0, 'hh' => 1.0, 'Wh' => 7.45699653134593E+02,
  223. 'wh' => 7.45699653134593E+02, 'flb' => 6.37047316692964E+07, 'BTU' => 2.54442605275546E+03,
  224. 'btu' => 2.54442605275546E+03),
  225. 'hh' => array('J' => 2.68451741316170E+06, 'e' => 2.68451612283024E+13,
  226. 'c' => 6.41616438565991E+05, 'cal' => 6.41186757845835E+05, 'eV' => 1.67553000000000E+25,
  227. 'ev' => 1.67553000000000E+25, 'HPh' => 1.0, 'hh' => 1.0, 'Wh' => 7.45699653134593E+02,
  228. 'wh' => 7.45699653134593E+02, 'flb' => 6.37047316692964E+07, 'BTU' => 2.54442605275546E+03,
  229. 'btu' => 2.54442605275546E+03),
  230. 'Wh' => array('J' => 3.59999820554720E+03, 'e' => 3.59999647518369E+10,
  231. 'c' => 8.60422069219046E+02, 'cal' => 8.59845857713046E+02, 'eV' => 2.24692340000000E+22,
  232. 'ev' => 2.24692340000000E+22, 'HPh' => 1.34102248243839E-03, 'hh' => 1.34102248243839E-03,
  233. 'Wh' => 1.0, 'wh' => 1.0, 'flb' => 8.54294774062316E+04, 'BTU' => 3.41213254164705E+00,
  234. 'btu' => 3.41213254164705E+00),
  235. 'wh' => array('J' => 3.59999820554720E+03, 'e' => 3.59999647518369E+10,
  236. 'c' => 8.60422069219046E+02, 'cal' => 8.59845857713046E+02, 'eV' => 2.24692340000000E+22,
  237. 'ev' => 2.24692340000000E+22, 'HPh' => 1.34102248243839E-03, 'hh' => 1.34102248243839E-03,
  238. 'Wh' => 1.0, 'wh' => 1.0, 'flb' => 8.54294774062316E+04, 'BTU' => 3.41213254164705E+00,
  239. 'btu' => 3.41213254164705E+00),
  240. 'flb' => array('J' => 4.21400003236424E-02, 'e' => 4.21399800687660E+05,
  241. 'c' => 1.00717234301644E-02, 'cal' => 1.00649785509554E-02, 'eV' => 2.63015000000000E+17,
  242. 'ev' => 2.63015000000000E+17, 'HPh' => 1.56974211145130E-08, 'hh' => 1.56974211145130E-08,
  243. 'Wh' => 1.17055614802000E-05, 'wh' => 1.17055614802000E-05, 'flb' => 1.0,
  244. 'BTU' => 3.99409272448406E-05, 'btu' => 3.99409272448406E-05),
  245. 'BTU' => array('J' => 1.05505813786749E+03, 'e' => 1.05505763074665E+10,
  246. 'c' => 2.52165488508168E+02, 'cal' => 2.51996617135510E+02, 'eV' => 6.58510000000000E+21,
  247. 'ev' => 6.58510000000000E+21, 'HPh' => 3.93015941224568E-04, 'hh' => 3.93015941224568E-04,
  248. 'Wh' => 2.93071851047526E-01, 'wh' => 2.93071851047526E-01, 'flb' => 2.50369750774671E+04,
  249. 'BTU' => 1.0, 'btu' => 1.0),
  250. 'btu' => array('J' => 1.05505813786749E+03, 'e' => 1.05505763074665E+10,
  251. 'c' => 2.52165488508168E+02, 'cal' => 2.51996617135510E+02, 'eV' => 6.58510000000000E+21,
  252. 'ev' => 6.58510000000000E+21, 'HPh' => 3.93015941224568E-04, 'hh' => 3.93015941224568E-04,
  253. 'Wh' => 2.93071851047526E-01, 'wh' => 2.93071851047526E-01, 'flb' => 2.50369750774671E+04,
  254. 'BTU' => 1.0, 'btu' => 1.0)),
  255. 'Power' => array(
  256. 'HP' => array('HP' => 1.0, 'h' => 1.0, 'W' => 7.45701000000000E+02, 'w' => 7.45701000000000E+02),
  257. 'h' => array('HP' => 1.0, 'h' => 1.0, 'W' => 7.45701000000000E+02, 'w' => 7.45701000000000E+02),
  258. 'W' => array('HP' => 1.34102006031908E-03, 'h' => 1.34102006031908E-03, 'W' => 1.0, 'w' => 1.0),
  259. 'w' => array('HP' => 1.34102006031908E-03, 'h' => 1.34102006031908E-03, 'W' => 1.0, 'w' => 1.0)),
  260. 'Magnetism' => array(
  261. 'T' => array('T' => 1.0, 'ga' => 10000.0),
  262. 'ga' => array('T' => 0.0001, 'ga' => 1.0)),
  263. 'Liquid' => array(
  264. 'tsp' => array('tsp' => 1.0, 'tbs' => 3.33333333333333E-01, 'oz' => 1.66666666666667E-01,
  265. 'cup' => 2.08333333333333E-02, 'pt' => 1.04166666666667E-02,
  266. 'us_pt' => 1.04166666666667E-02, 'uk_pt' => 8.67558516821960E-03,
  267. 'qt' => 5.20833333333333E-03, 'gal' => 1.30208333333333E-03, 'l' => 4.92999408400710E-03,
  268. 'lt' => 4.92999408400710E-03),
  269. 'tbs' => array('tsp' => 3.00000000000000E+00, 'tbs' => 1.0, 'oz' => 5.00000000000000E-01,
  270. 'cup' => 6.25000000000000E-02, 'pt' => 3.12500000000000E-02,
  271. 'us_pt' => 3.12500000000000E-02, 'uk_pt' => 2.60267555046588E-02,
  272. 'qt' => 1.56250000000000E-02, 'gal' => 3.90625000000000E-03, 'l' => 1.47899822520213E-02,
  273. 'lt' => 1.47899822520213E-02),
  274. 'oz' => array('tsp' => 6.00000000000000E+00, 'tbs' => 2.00000000000000E+00, 'oz' => 1.0,
  275. 'cup' => 1.25000000000000E-01, 'pt' => 6.25000000000000E-02,
  276. 'us_pt' => 6.25000000000000E-02, 'uk_pt' => 5.20535110093176E-02,
  277. 'qt' => 3.12500000000000E-02, 'gal' => 7.81250000000000E-03, 'l' => 2.95799645040426E-02,
  278. 'lt' => 2.95799645040426E-02),
  279. 'cup' => array('tsp' => 4.80000000000000E+01, 'tbs' => 1.60000000000000E+01,
  280. 'oz' => 8.00000000000000E+00, 'cup' => 1.0, 'pt' => 5.00000000000000E-01,
  281. 'us_pt' => 5.00000000000000E-01, 'uk_pt' => 4.16428088074541E-01,
  282. 'qt' => 2.50000000000000E-01, 'gal' => 6.25000000000000E-02, 'l' => 2.36639716032341E-01,
  283. 'lt' => 2.36639716032341E-01),
  284. 'pt' => array('tsp' => 9.60000000000000E+01, 'tbs' => 3.20000000000000E+01,
  285. 'oz' => 1.60000000000000E+01, 'cup' => 2.00000000000000E+00, 'pt' => 1.0, 'us_pt' => 1.0,
  286. 'uk_pt' => 8.32856176149081E-01, 'qt' => 5.00000000000000E-01,
  287. 'gal' => 1.25000000000000E-01, 'l' => 4.73279432064682E-01, 'lt' => 4.73279432064682E-01),
  288. 'us_pt' => array('tsp' => 9.60000000000000E+01, 'tbs' => 3.20000000000000E+01,
  289. 'oz' => 1.60000000000000E+01, 'cup' => 2.00000000000000E+00, 'pt' => 1.0, 'us_pt' => 1.0,
  290. 'uk_pt' => 8.32856176149081E-01, 'qt' => 5.00000000000000E-01,
  291. 'gal' => 1.25000000000000E-01, 'l' => 4.73279432064682E-01, 'lt' => 4.73279432064682E-01),
  292. 'uk_pt' => array('tsp' => 1.15266000000000E+02, 'tbs' => 3.84220000000000E+01,
  293. 'oz' => 1.92110000000000E+01, 'cup' => 2.40137500000000E+00, 'pt' => 1.20068750000000E+00,
  294. 'us_pt' => 1.20068750000000E+00, 'uk_pt' => 1.0, 'qt' => 6.00343750000000E-01,
  295. 'gal' => 1.50085937500000E-01, 'l' => 5.68260698087162E-01, 'lt' => 5.68260698087162E-01),
  296. 'qt' => array('tsp' => 1.92000000000000E+02, 'tbs' => 6.40000000000000E+01,
  297. 'oz' => 3.20000000000000E+01, 'cup' => 4.00000000000000E+00, 'pt' => 2.00000000000000E+00,
  298. 'us_pt' => 2.00000000000000E+00, 'uk_pt' => 1.66571235229816E+00, 'qt' => 1.0,
  299. 'gal' => 2.50000000000000E-01, 'l' => 9.46558864129363E-01, 'lt' => 9.46558864129363E-01),
  300. 'gal' => array('tsp' => 7.68000000000000E+02, 'tbs' => 2.56000000000000E+02,
  301. 'oz' => 1.28000000000000E+02, 'cup' => 1.60000000000000E+01, 'pt' => 8.00000000000000E+00,
  302. 'us_pt' => 8.00000000000000E+00, 'uk_pt' => 6.66284940919265E+00,
  303. 'qt' => 4.00000000000000E+00, 'gal' => 1.0, 'l' => 3.78623545651745E+00,
  304. 'lt' => 3.78623545651745E+00),
  305. 'l' => array('tsp' => 2.02840000000000E+02, 'tbs' => 6.76133333333333E+01,
  306. 'oz' => 3.38066666666667E+01, 'cup' => 4.22583333333333E+00, 'pt' => 2.11291666666667E+00,
  307. 'us_pt' => 2.11291666666667E+00, 'uk_pt' => 1.75975569552166E+00,
  308. 'qt' => 1.05645833333333E+00, 'gal' => 2.64114583333333E-01, 'l' => 1.0, 'lt' => 1.0),
  309. 'lt' => array('tsp' => 2.02840000000000E+02, 'tbs' => 6.76133333333333E+01,
  310. 'oz' => 3.38066666666667E+01, 'cup' => 4.22583333333333E+00, 'pt' => 2.11291666666667E+00,
  311. 'us_pt' => 2.11291666666667E+00, 'uk_pt' => 1.75975569552166E+00,
  312. 'qt' => 1.05645833333333E+00, 'gal' => 2.64114583333333E-01, 'l' => 1.0, 'lt' => 1.0)));
  313. public static function _parseComplex($complexNumber)
  314. {
  315. $workString = (string) $complexNumber;
  316. $realNumber = $imaginary = 0;
  317. // Extract the suffix, if there is one
  318. $suffix = substr($workString, - 1);
  319. if (! is_numeric($suffix))
  320. {
  321. $workString = substr($workString, 0, - 1);
  322. }
  323. else
  324. {
  325. $suffix = '';
  326. }
  327. // Split the input into its Real and Imaginary components
  328. $leadingSign = 0;
  329. if (strlen($workString) > 0)
  330. {
  331. $leadingSign = (($workString{0} == '+') || ($workString{0} == '-')) ? 1 : 0;
  332. }
  333. $power = '';
  334. $realNumber = strtok($workString, '+-');
  335. if (strtoupper(substr($realNumber, - 1)) == 'E')
  336. {
  337. $power = strtok('+-');
  338. ++ $leadingSign;
  339. }
  340. $realNumber = substr($workString, 0, strlen($realNumber) + strlen($power) + $leadingSign);
  341. if ($suffix != '')
  342. {
  343. $imaginary = substr($workString, strlen($realNumber));
  344. if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-')))
  345. {
  346. $imaginary = $realNumber . '1';
  347. $realNumber = '0';
  348. }
  349. else
  350. if ($imaginary == '')
  351. {
  352. $imaginary = $realNumber;
  353. $realNumber = '0';
  354. }
  355. elseif (($imaginary == '+') || ($imaginary == '-'))
  356. {
  357. $imaginary .= '1';
  358. }
  359. }
  360. return array('real' => $realNumber, 'imaginary' => $imaginary, 'suffix' => $suffix);
  361. } // function _parseComplex()
  362. private static function _cleanComplex($complexNumber)
  363. {
  364. if ($complexNumber{0} == '+')
  365. $complexNumber = substr($complexNumber, 1);
  366. if ($complexNumber{0} == '0')
  367. $complexNumber = substr($complexNumber, 1);
  368. if ($complexNumber{0} == '.')
  369. $complexNumber = '0' . $complexNumber;
  370. if ($complexNumber{0} == '+')
  371. $complexNumber = substr($complexNumber, 1);
  372. return $complexNumber;
  373. }
  374. private static function _nbrConversionFormat($xVal, $places)
  375. {
  376. if (! is_null($places))
  377. {
  378. if (strlen($xVal) <= $places)
  379. {
  380. return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), - 10);
  381. }
  382. else
  383. {
  384. return PHPExcel_Calculation_Functions :: NaN();
  385. }
  386. }
  387. return substr($xVal, - 10);
  388. } // function _nbrConversionFormat()
  389. /**
  390. * BESSELI
  391. *
  392. * Returns the modified Bessel function, which is equivalent to the Bessel function evaluated for purely imaginary arguments
  393. *
  394. * @param float $x
  395. * @param float $n
  396. * @return int
  397. */
  398. public static function BESSELI($x, $n)
  399. {
  400. $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  401. $n = (is_null($n)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($n);
  402. if ((is_numeric($x)) && (is_numeric($n)))
  403. {
  404. $n = floor($n);
  405. if ($n < 0)
  406. {
  407. return PHPExcel_Calculation_Functions :: NaN();
  408. }
  409. $f_2_PI = 2 * M_PI;
  410. if (abs($x) <= 30)
  411. {
  412. $fTerm = pow($x / 2, $n) / PHPExcel_Calculation_MathTrig :: FACT($n);
  413. $nK = 1;
  414. $fResult = $fTerm;
  415. $fSqrX = ($x * $x) / 4;
  416. do
  417. {
  418. $fTerm *= $fSqrX;
  419. $fTerm /= ($nK * ($nK + $n));
  420. $fResult += $fTerm;
  421. }
  422. while ((abs($fTerm) > 1e-10) && (++ $nK < 100));
  423. }
  424. else
  425. {
  426. $fXAbs = abs($x);
  427. $fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs);
  428. if (($n && 1) && ($x < 0))
  429. {
  430. $fResult = - $fResult;
  431. }
  432. }
  433. return $fResult;
  434. }
  435. return PHPExcel_Calculation_Functions :: VALUE();
  436. } // function BESSELI()
  437. /**
  438. * BESSELJ
  439. *
  440. * Returns the Bessel function
  441. *
  442. * @param float $x
  443. * @param float $n
  444. * @return int
  445. */
  446. public static function BESSELJ($x, $n)
  447. {
  448. $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  449. $n = (is_null($n)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($n);
  450. if ((is_numeric($x)) && (is_numeric($n)))
  451. {
  452. $n = floor($n);
  453. if ($n < 0)
  454. {
  455. return PHPExcel_Calculation_Functions :: NaN();
  456. }
  457. $f_PI_DIV_2 = M_PI / 2;
  458. $f_PI_DIV_4 = M_PI / 4;
  459. $fResult = 0;
  460. if (abs($x) <= 30)
  461. {
  462. $fTerm = pow($x / 2, $n) / PHPExcel_Calculation_MathTrig :: FACT($n);
  463. $nK = 1;
  464. $fResult = $fTerm;
  465. $fSqrX = ($x * $x) / - 4;
  466. do
  467. {
  468. $fTerm *= $fSqrX;
  469. $fTerm /= ($nK * ($nK + $n));
  470. $fResult += $fTerm;
  471. }
  472. while ((abs($fTerm) > 1e-10) && (++ $nK < 100));
  473. }
  474. else
  475. {
  476. $fXAbs = abs($x);
  477. $fResult = sqrt(M_2DIVPI / $fXAbs) * cos($fXAbs - $n * $f_PI_DIV_2 - $f_PI_DIV_4);
  478. if (($n && 1) && ($x < 0))
  479. {
  480. $fResult = - $fResult;
  481. }
  482. }
  483. return $fResult;
  484. }
  485. return PHPExcel_Calculation_Functions :: VALUE();
  486. } // function BESSELJ()
  487. private static function _Besselk0($fNum)
  488. {
  489. if ($fNum <= 2)
  490. {
  491. $fNum2 = $fNum * 0.5;
  492. $y = ($fNum2 * $fNum2);
  493. $fRet = - log($fNum2) * self :: BESSELI($fNum, 0) + (- 0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * (0.10750e-3 + $y * 0.74e-5))))));
  494. }
  495. else
  496. {
  497. $y = 2 / $fNum;
  498. $fRet = exp(- $fNum) / sqrt($fNum) * (1.25331414 + $y * (- 0.7832358e-1 + $y * (0.2189568e-1 + $y * (- 0.1062446e-1 + $y * (0.587872e-2 + $y * (- 0.251540e-2 + $y * 0.53208e-3))))));
  499. }
  500. return $fRet;
  501. } // function _Besselk0()
  502. private static function _Besselk1($fNum)
  503. {
  504. if ($fNum <= 2)
  505. {
  506. $fNum2 = $fNum * 0.5;
  507. $y = ($fNum2 * $fNum2);
  508. $fRet = log($fNum2) * self :: BESSELI($fNum, 1) + (1 + $y * (0.15443144 + $y * (- 0.67278579 + $y * (- 0.18156897 + $y * (- 0.1919402e-1 + $y * (- 0.110404e-2 + $y * (- 0.4686e-4))))))) / $fNum;
  509. }
  510. else
  511. {
  512. $y = 2 / $fNum;
  513. $fRet = exp(- $fNum) / sqrt($fNum) * (1.25331414 + $y * (0.23498619 + $y * (- 0.3655620e-1 + $y * (0.1504268e-1 + $y * (- 0.780353e-2 + $y * (0.325614e-2 + $y * (- 0.68245e-3)))))));
  514. }
  515. return $fRet;
  516. } // function _Besselk1()
  517. /**
  518. * BESSELK
  519. *
  520. * Returns the modified Bessel function, which is equivalent to the Bessel functions evaluated for purely imaginary arguments.
  521. *
  522. * @param float $x
  523. * @param float $ord
  524. * @return float
  525. */
  526. public static function BESSELK($x, $ord)
  527. {
  528. $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  529. $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($ord);
  530. if ((is_numeric($x)) && (is_numeric($ord)))
  531. {
  532. if (($ord < 0) || ($x == 0.0))
  533. {
  534. return PHPExcel_Calculation_Functions :: NaN();
  535. }
  536. switch (floor($ord))
  537. {
  538. case 0 :
  539. return self :: _Besselk0($x);
  540. break;
  541. case 1 :
  542. return self :: _Besselk1($x);
  543. break;
  544. default :
  545. $fTox = 2 / $x;
  546. $fBkm = self :: _Besselk0($x);
  547. $fBk = self :: _Besselk1($x);
  548. for($n = 1; $n < $ord; ++ $n)
  549. {
  550. $fBkp = $fBkm + $n * $fTox * $fBk;
  551. $fBkm = $fBk;
  552. $fBk = $fBkp;
  553. }
  554. }
  555. return $fBk;
  556. }
  557. return PHPExcel_Calculation_Functions :: VALUE();
  558. } // function BESSELK()
  559. private static function _Bessely0($fNum)
  560. {
  561. if ($fNum < 8.0)
  562. {
  563. $y = ($fNum * $fNum);
  564. $f1 = - 2957821389.0 + $y * (7062834065.0 + $y * (- 512359803.6 + $y * (10879881.29 + $y * (- 86327.92757 + $y * 228.4622733))));
  565. $f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y))));
  566. $fRet = $f1 / $f2 + M_2DIVPI * self :: BESSELJ($fNum, 0) * log($fNum);
  567. }
  568. else
  569. {
  570. $z = 8.0 / $fNum;
  571. $y = ($z * $z);
  572. $xx = $fNum - 0.785398164;
  573. $f1 = 1 + $y * (- 0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (- 0.2073370639e-5 + $y * 0.2093887211e-6)));
  574. $f2 = - 0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (- 0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (- 0.934945152e-7))));
  575. $fRet = sqrt(M_2DIVPI / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2);
  576. }
  577. return $fRet;
  578. } // function _Bessely0()
  579. private static function _Bessely1($fNum)
  580. {
  581. if ($fNum < 8.0)
  582. {
  583. $y = ($fNum * $fNum);
  584. $f1 = $fNum * (- 0.4900604943e13 + $y * (0.1275274390e13 + $y * (- 0.5153438139e11 + $y * (0.7349264551e9 + $y * (- 0.4237922726e7 + $y * 0.8511937935e4)))));
  585. $f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y * (0.1020426050e6 + $y * (0.3549632885e3 + $y)))));
  586. $fRet = $f1 / $f2 + M_2DIVPI * (self :: BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum);
  587. }
  588. else
  589. {
  590. $z = 8.0 / $fNum;
  591. $y = ($z * $z);
  592. $xx = $fNum - 2.356194491;
  593. $f1 = 1 + $y * (0.183105e-2 + $y * (- 0.3516396496e-4 + $y * (0.2457520174e-5 + $y * (- 0.240337019e6))));
  594. $f2 = 0.04687499995 + $y * (- 0.2002690873e-3 + $y * (0.8449199096e-5 + $y * (- 0.88228987e-6 + $y * 0.105787412e-6)));
  595. $fRet = sqrt(M_2DIVPI / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2);
  596. #i12430# ...but this seems to work much better.
  597. // $fRet = sqrt(M_2DIVPI / $fNum) * sin($fNum - 2.356194491);
  598. }
  599. return $fRet;
  600. } // function _Bessely1()
  601. /**
  602. * BESSELY
  603. *
  604. * Returns the Bessel function, which is also called the Weber function or the Neumann function.
  605. *
  606. * @param float $x
  607. * @param float $n
  608. * @return int
  609. */
  610. public static function BESSELY($x, $ord)
  611. {
  612. $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  613. $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions :: flattenSingleValue($ord);
  614. if ((is_numeric($x)) && (is_numeric($ord)))
  615. {
  616. if (($ord < 0) || ($x == 0.0))
  617. {
  618. return PHPExcel_Calculation_Functions :: NaN();
  619. }
  620. switch (floor($ord))
  621. {
  622. case 0 :
  623. return self :: _Bessely0($x);
  624. break;
  625. case 1 :
  626. return self :: _Bessely1($x);
  627. break;
  628. default :
  629. $fTox = 2 / $x;
  630. $fBym = self :: _Bessely0($x);
  631. $fBy = self :: _Bessely1($x);
  632. for($n = 1; $n < $ord; ++ $n)
  633. {
  634. $fByp = $n * $fTox * $fBy - $fBym;
  635. $fBym = $fBy;
  636. $fBy = $fByp;
  637. }
  638. }
  639. return $fBy;
  640. }
  641. return PHPExcel_Calculation_Functions :: VALUE();
  642. } // function BESSELY()
  643. /**
  644. * BINTODEC
  645. *
  646. * Return a binary value as Decimal.
  647. *
  648. * @param string $x
  649. * @return string
  650. */
  651. public static function BINTODEC($x)
  652. {
  653. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  654. if (is_bool($x))
  655. {
  656. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_OPENOFFICE)
  657. {
  658. $x = (int) $x;
  659. }
  660. else
  661. {
  662. return PHPExcel_Calculation_Functions :: VALUE();
  663. }
  664. }
  665. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_GNUMERIC)
  666. {
  667. $x = floor($x);
  668. }
  669. $x = (string) $x;
  670. if (strlen($x) > preg_match_all('/[01]/', $x, $out))
  671. {
  672. return PHPExcel_Calculation_Functions :: NaN();
  673. }
  674. if (strlen($x) > 10)
  675. {
  676. return PHPExcel_Calculation_Functions :: NaN();
  677. }
  678. elseif (strlen($x) == 10)
  679. {
  680. // Two's Complement
  681. $x = substr($x, - 9);
  682. return '-' . (512 - bindec($x));
  683. }
  684. return bindec($x);
  685. } // function BINTODEC()
  686. /**
  687. * BINTOHEX
  688. *
  689. * Return a binary value as Hex.
  690. *
  691. * @param string $x
  692. * @return string
  693. */
  694. public static function BINTOHEX($x, $places = null)
  695. {
  696. $x = floor(PHPExcel_Calculation_Functions :: flattenSingleValue($x));
  697. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  698. if (is_bool($x))
  699. {
  700. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_OPENOFFICE)
  701. {
  702. $x = (int) $x;
  703. }
  704. else
  705. {
  706. return PHPExcel_Calculation_Functions :: VALUE();
  707. }
  708. }
  709. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_GNUMERIC)
  710. {
  711. $x = floor($x);
  712. }
  713. $x = (string) $x;
  714. if (strlen($x) > preg_match_all('/[01]/', $x, $out))
  715. {
  716. return PHPExcel_Calculation_Functions :: NaN();
  717. }
  718. if (strlen($x) > 10)
  719. {
  720. return PHPExcel_Calculation_Functions :: NaN();
  721. }
  722. elseif (strlen($x) == 10)
  723. {
  724. // Two's Complement
  725. return str_repeat('F', 8) . substr(strtoupper(dechex(bindec(substr($x, - 9)))), - 2);
  726. }
  727. $hexVal = (string) strtoupper(dechex(bindec($x)));
  728. return self :: _nbrConversionFormat($hexVal, $places);
  729. } // function BINTOHEX()
  730. /**
  731. * BINTOOCT
  732. *
  733. * Return a binary value as Octal.
  734. *
  735. * @param string $x
  736. * @return string
  737. */
  738. public static function BINTOOCT($x, $places = null)
  739. {
  740. $x = floor(PHPExcel_Calculation_Functions :: flattenSingleValue($x));
  741. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  742. if (is_bool($x))
  743. {
  744. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_OPENOFFICE)
  745. {
  746. $x = (int) $x;
  747. }
  748. else
  749. {
  750. return PHPExcel_Calculation_Functions :: VALUE();
  751. }
  752. }
  753. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_GNUMERIC)
  754. {
  755. $x = floor($x);
  756. }
  757. $x = (string) $x;
  758. if (strlen($x) > preg_match_all('/[01]/', $x, $out))
  759. {
  760. return PHPExcel_Calculation_Functions :: NaN();
  761. }
  762. if (strlen($x) > 10)
  763. {
  764. return PHPExcel_Calculation_Functions :: NaN();
  765. }
  766. elseif (strlen($x) == 10)
  767. {
  768. // Two's Complement
  769. return str_repeat('7', 7) . substr(strtoupper(decoct(bindec(substr($x, - 9)))), - 3);
  770. }
  771. $octVal = (string) decoct(bindec($x));
  772. return self :: _nbrConversionFormat($octVal, $places);
  773. } // function BINTOOCT()
  774. /**
  775. * DECTOBIN
  776. *
  777. * Return an octal value as binary.
  778. *
  779. * @param string $x
  780. * @return string
  781. */
  782. public static function DECTOBIN($x, $places = null)
  783. {
  784. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  785. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  786. if (is_bool($x))
  787. {
  788. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_OPENOFFICE)
  789. {
  790. $x = (int) $x;
  791. }
  792. else
  793. {
  794. return PHPExcel_Calculation_Functions :: VALUE();
  795. }
  796. }
  797. $x = (string) $x;
  798. if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out))
  799. {
  800. return PHPExcel_Calculation_Functions :: VALUE();
  801. }
  802. $x = (string) floor($x);
  803. $r = decbin($x);
  804. if (strlen($r) == 32)
  805. {
  806. // Two's Complement
  807. $r = substr($r, - 10);
  808. }
  809. elseif (strlen($r) > 11)
  810. {
  811. return PHPExcel_Calculation_Functions :: NaN();
  812. }
  813. return self :: _nbrConversionFormat($r, $places);
  814. } // function DECTOBIN()
  815. /**
  816. * DECTOHEX
  817. *
  818. * Return an octal value as binary.
  819. *
  820. * @param string $x
  821. * @return string
  822. */
  823. public static function DECTOHEX($x, $places = null)
  824. {
  825. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  826. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  827. if (is_bool($x))
  828. {
  829. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_OPENOFFICE)
  830. {
  831. $x = (int) $x;
  832. }
  833. else
  834. {
  835. return PHPExcel_Calculation_Functions :: VALUE();
  836. }
  837. }
  838. $x = (string) $x;
  839. if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out))
  840. {
  841. return PHPExcel_Calculation_Functions :: VALUE();
  842. }
  843. $x = (string) floor($x);
  844. $r = strtoupper(dechex($x));
  845. if (strlen($r) == 8)
  846. {
  847. // Two's Complement
  848. $r = 'FF' . $r;
  849. }
  850. return self :: _nbrConversionFormat($r, $places);
  851. } // function DECTOHEX()
  852. /**
  853. * DECTOOCT
  854. *
  855. * Return an octal value as binary.
  856. *
  857. * @param string $x
  858. * @return string
  859. */
  860. public static function DECTOOCT($x, $places = null)
  861. {
  862. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  863. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  864. if (is_bool($x))
  865. {
  866. if (PHPExcel_Calculation_Functions :: getCompatibilityMode() == PHPExcel_Calculation_Functions :: COMPATIBILITY_OPENOFFICE)
  867. {
  868. $x = (int) $x;
  869. }
  870. else
  871. {
  872. return PHPExcel_Calculation_Functions :: VALUE();
  873. }
  874. }
  875. $x = (string) $x;
  876. if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out))
  877. {
  878. return PHPExcel_Calculation_Functions :: VALUE();
  879. }
  880. $x = (string) floor($x);
  881. $r = decoct($x);
  882. if (strlen($r) == 11)
  883. {
  884. // Two's Complement
  885. $r = substr($r, - 10);
  886. }
  887. return self :: _nbrConversionFormat($r, $places);
  888. } // function DECTOOCT()
  889. /**
  890. * HEXTOBIN
  891. *
  892. * Return a hex value as binary.
  893. *
  894. * @param string $x
  895. * @return string
  896. */
  897. public static function HEXTOBIN($x, $places = null)
  898. {
  899. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  900. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  901. if (is_bool($x))
  902. {
  903. return PHPExcel_Calculation_Functions :: VALUE();
  904. }
  905. $x = (string) $x;
  906. if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out))
  907. {
  908. return PHPExcel_Calculation_Functions :: NaN();
  909. }
  910. $binVal = decbin(hexdec($x));
  911. return substr(self :: _nbrConversionFormat($binVal, $places), - 10);
  912. } // function HEXTOBIN()
  913. /**
  914. * HEXTODEC
  915. *
  916. * Return a hex value as octal.
  917. *
  918. * @param string $x
  919. * @return string
  920. */
  921. public static function HEXTODEC($x)
  922. {
  923. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  924. if (is_bool($x))
  925. {
  926. return PHPExcel_Calculation_Functions :: VALUE();
  927. }
  928. $x = (string) $x;
  929. if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out))
  930. {
  931. return PHPExcel_Calculation_Functions :: NaN();
  932. }
  933. return hexdec($x);
  934. } // function HEXTODEC()
  935. /**
  936. * HEXTOOCT
  937. *
  938. * Return a hex value as octal.
  939. *
  940. * @param string $x
  941. * @return string
  942. */
  943. public static function HEXTOOCT($x, $places = null)
  944. {
  945. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  946. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  947. if (is_bool($x))
  948. {
  949. return PHPExcel_Calculation_Functions :: VALUE();
  950. }
  951. $x = (string) $x;
  952. if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out))
  953. {
  954. return PHPExcel_Calculation_Functions :: NaN();
  955. }
  956. $octVal = decoct(hexdec($x));
  957. return self :: _nbrConversionFormat($octVal, $places);
  958. } // function HEXTOOCT()
  959. /**
  960. * OCTTOBIN
  961. *
  962. * Return an octal value as binary.
  963. *
  964. * @param string $x
  965. * @return string
  966. */
  967. public static function OCTTOBIN($x, $places = null)
  968. {
  969. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  970. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  971. if (is_bool($x))
  972. {
  973. return PHPExcel_Calculation_Functions :: VALUE();
  974. }
  975. $x = (string) $x;
  976. if (preg_match_all('/[01234567]/', $x, $out) != strlen($x))
  977. {
  978. return PHPExcel_Calculation_Functions :: NaN();
  979. }
  980. $r = decbin(octdec($x));
  981. return self :: _nbrConversionFormat($r, $places);
  982. } // function OCTTOBIN()
  983. /**
  984. * OCTTODEC
  985. *
  986. * Return an octal value as binary.
  987. *
  988. * @param string $x
  989. * @return string
  990. */
  991. public static function OCTTODEC($x)
  992. {
  993. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  994. if (is_bool($x))
  995. {
  996. return PHPExcel_Calculation_Functions :: VALUE();
  997. }
  998. $x = (string) $x;
  999. if (preg_match_all('/[01234567]/', $x, $out) != strlen($x))
  1000. {
  1001. return PHPExcel_Calculation_Functions :: NaN();
  1002. }
  1003. return octdec($x);
  1004. } // function OCTTODEC()
  1005. /**
  1006. * OCTTOHEX
  1007. *
  1008. * Return an octal value as hex.
  1009. *
  1010. * @param string $x
  1011. * @return string
  1012. */
  1013. public static function OCTTOHEX($x, $places = null)
  1014. {
  1015. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  1016. $places = PHPExcel_Calculation_Functions :: flattenSingleValue($places);
  1017. if (is_bool($x))
  1018. {
  1019. return PHPExcel_Calculation_Functions :: VALUE();
  1020. }
  1021. $x = (string) $x;
  1022. if (preg_match_all('/[01234567]/', $x, $out) != strlen($x))
  1023. {
  1024. return PHPExcel_Calculation_Functions :: NaN();
  1025. }
  1026. $hexVal = strtoupper(dechex(octdec($x)));
  1027. return self :: _nbrConversionFormat($hexVal, $places);
  1028. } // function OCTTOHEX()
  1029. /**
  1030. * COMPLEX
  1031. *
  1032. * returns a complex number of the form x + yi or x + yj.
  1033. *
  1034. * @param float $realNumber
  1035. * @param float $imaginary
  1036. * @param string $suffix
  1037. * @return string
  1038. */
  1039. public static function COMPLEX($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i')
  1040. {
  1041. $realNumber = (is_null($realNumber)) ? 0.0 : (float) PHPExcel_Calculation_Functions :: flattenSingleValue($realNumber);
  1042. $imaginary = (is_null($imaginary)) ? 0.0 : (float) PHPExcel_Calculation_Functions :: flattenSingleValue($imaginary);
  1043. $suffix = (is_null($suffix)) ? 'i' : PHPExcel_Calculation_Functions :: flattenSingleValue($suffix);
  1044. if (((is_numeric($realNumber)) && (is_numeric($imaginary))) && (($suffix == 'i') || ($suffix == 'j') || ($suffix == '')))
  1045. {
  1046. if ($suffix == '')
  1047. $suffix = 'i';
  1048. if ($realNumber == 0.0)
  1049. {
  1050. if ($imaginary == 0.0)
  1051. {
  1052. return (string) '0';
  1053. }
  1054. elseif ($imaginary == 1.0)
  1055. {
  1056. return (string) $suffix;
  1057. }
  1058. elseif ($imaginary == - 1.0)
  1059. {
  1060. return (string) '-' . $suffix;
  1061. }
  1062. return (string) $imaginary . $suffix;
  1063. }
  1064. elseif ($imaginary == 0.0)
  1065. {
  1066. return (string) $realNumber;
  1067. }
  1068. elseif ($imaginary == 1.0)
  1069. {
  1070. return (string) $realNumber . '+' . $suffix;
  1071. }
  1072. elseif ($imaginary == - 1.0)
  1073. {
  1074. return (string) $realNumber . '-' . $suffix;
  1075. }
  1076. if ($imaginary > 0)
  1077. {
  1078. $imaginary = (string) '+' . $imaginary;
  1079. }
  1080. return (string) $realNumber . $imaginary . $suffix;
  1081. }
  1082. return PHPExcel_Calculation_Functions :: VALUE();
  1083. } // function COMPLEX()
  1084. /**
  1085. * IMAGINARY
  1086. *
  1087. * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format.
  1088. *
  1089. * @param string $complexNumber
  1090. * @return real
  1091. */
  1092. public static function IMAGINARY($complexNumber)
  1093. {
  1094. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1095. $parsedComplex = self :: _parseComplex($complexNumber);
  1096. if (! is_array($parsedComplex))
  1097. {
  1098. return $parsedComplex;
  1099. }
  1100. return $parsedComplex['imaginary'];
  1101. } // function IMAGINARY()
  1102. /**
  1103. * IMREAL
  1104. *
  1105. * Returns the real coefficient of a complex number in x + yi or x + yj text format.
  1106. *
  1107. * @param string $complexNumber
  1108. * @return real
  1109. */
  1110. public static function IMREAL($complexNumber)
  1111. {
  1112. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1113. $parsedComplex = self :: _parseComplex($complexNumber);
  1114. if (! is_array($parsedComplex))
  1115. {
  1116. return $parsedComplex;
  1117. }
  1118. return $parsedComplex['real'];
  1119. } // function IMREAL()
  1120. /**
  1121. * IMABS
  1122. *
  1123. * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format.
  1124. *
  1125. * @param string $complexNumber
  1126. * @return real
  1127. */
  1128. public static function IMABS($complexNumber)
  1129. {
  1130. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1131. $parsedComplex = self :: _parseComplex($complexNumber);
  1132. if (! is_array($parsedComplex))
  1133. {
  1134. return $parsedComplex;
  1135. }
  1136. return sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']));
  1137. } // function IMABS()
  1138. /**
  1139. * IMARGUMENT
  1140. *
  1141. * Returns the argument theta of a complex number, i.e. the angle in radians from the real axis to the representation of the number in polar coordinates.
  1142. *
  1143. * @param string $complexNumber
  1144. * @return string
  1145. */
  1146. public static function IMARGUMENT($complexNumber)
  1147. {
  1148. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1149. $parsedComplex = self :: _parseComplex($complexNumber);
  1150. if (! is_array($parsedComplex))
  1151. {
  1152. return $parsedComplex;
  1153. }
  1154. if ($parsedComplex['real'] == 0.0)
  1155. {
  1156. if ($parsedComplex['imaginary'] == 0.0)
  1157. {
  1158. return 0.0;
  1159. }
  1160. elseif ($parsedComplex['imaginary'] < 0.0)
  1161. {
  1162. return M_PI / - 2;
  1163. }
  1164. else
  1165. {
  1166. return M_PI / 2;
  1167. }
  1168. }
  1169. elseif ($parsedComplex['real'] > 0.0)
  1170. {
  1171. return atan($parsedComplex['imaginary'] / $parsedComplex['real']);
  1172. }
  1173. elseif ($parsedComplex['imaginary'] < 0.0)
  1174. {
  1175. return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real'])));
  1176. }
  1177. else
  1178. {
  1179. return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real']));
  1180. }
  1181. } // function IMARGUMENT()
  1182. /**
  1183. * IMCONJUGATE
  1184. *
  1185. * Returns the complex conjugate of a complex number in x + yi or x + yj text format.
  1186. *
  1187. * @param string $complexNumber
  1188. * @return string
  1189. */
  1190. public static function IMCONJUGATE($complexNumber)
  1191. {
  1192. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1193. $parsedComplex = self :: _parseComplex($complexNumber);
  1194. if (! is_array($parsedComplex))
  1195. {
  1196. return $parsedComplex;
  1197. }
  1198. if ($parsedComplex['imaginary'] == 0.0)
  1199. {
  1200. return $parsedComplex['real'];
  1201. }
  1202. else
  1203. {
  1204. return self :: _cleanComplex(self :: COMPLEX($parsedComplex['real'], 0 - $parsedComplex['imaginary'], $parsedComplex['suffix']));
  1205. }
  1206. } // function IMCONJUGATE()
  1207. /**
  1208. * IMCOS
  1209. *
  1210. * Returns the cosine of a complex number in x + yi or x + yj text format.
  1211. *
  1212. * @param string $complexNumber
  1213. * @return string
  1214. */
  1215. public static function IMCOS($complexNumber)
  1216. {
  1217. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1218. $parsedComplex = self :: _parseComplex($complexNumber);
  1219. if (! is_array($parsedComplex))
  1220. {
  1221. return $parsedComplex;
  1222. }
  1223. if ($parsedComplex['imaginary'] == 0.0)
  1224. {
  1225. return cos($parsedComplex['real']);
  1226. }
  1227. else
  1228. {
  1229. return self :: IMCONJUGATE(self :: COMPLEX(cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']), sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']), $parsedComplex['suffix']));
  1230. }
  1231. } // function IMCOS()
  1232. /**
  1233. * IMSIN
  1234. *
  1235. * Returns the sine of a complex number in x + yi or x + yj text format.
  1236. *
  1237. * @param string $complexNumber
  1238. * @return string
  1239. */
  1240. public static function IMSIN($complexNumber)
  1241. {
  1242. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1243. $parsedComplex = self :: _parseComplex($complexNumber);
  1244. if (! is_array($parsedComplex))
  1245. {
  1246. return $parsedComplex;
  1247. }
  1248. if ($parsedComplex['imaginary'] == 0.0)
  1249. {
  1250. return sin($parsedComplex['real']);
  1251. }
  1252. else
  1253. {
  1254. return self :: COMPLEX(sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']), cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']), $parsedComplex['suffix']);
  1255. }
  1256. } // function IMSIN()
  1257. /**
  1258. * IMSQRT
  1259. *
  1260. * Returns the square root of a complex number in x + yi or x + yj text format.
  1261. *
  1262. * @param string $complexNumber
  1263. * @return string
  1264. */
  1265. public static function IMSQRT($complexNumber)
  1266. {
  1267. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1268. $parsedComplex = self :: _parseComplex($complexNumber);
  1269. if (! is_array($parsedComplex))
  1270. {
  1271. return $parsedComplex;
  1272. }
  1273. $theta = self :: IMARGUMENT($complexNumber);
  1274. $d1 = cos($theta / 2);
  1275. $d2 = sin($theta / 2);
  1276. $r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));
  1277. if ($parsedComplex['suffix'] == '')
  1278. {
  1279. return self :: COMPLEX($d1 * $r, $d2 * $r);
  1280. }
  1281. else
  1282. {
  1283. return self :: COMPLEX($d1 * $r, $d2 * $r, $parsedComplex['suffix']);
  1284. }
  1285. } // function IMSQRT()
  1286. /**
  1287. * IMLN
  1288. *
  1289. * Returns the natural logarithm of a complex number in x + yi or x + yj text format.
  1290. *
  1291. * @param string $complexNumber
  1292. * @return string
  1293. */
  1294. public static function IMLN($complexNumber)
  1295. {
  1296. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1297. $parsedComplex = self :: _parseComplex($complexNumber);
  1298. if (! is_array($parsedComplex))
  1299. {
  1300. return $parsedComplex;
  1301. }
  1302. if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0))
  1303. {
  1304. return PHPExcel_Calculation_Functions :: NaN();
  1305. }
  1306. $logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));
  1307. $t = self :: IMARGUMENT($complexNumber);
  1308. if ($parsedComplex['suffix'] == '')
  1309. {
  1310. return self :: COMPLEX($logR, $t);
  1311. }
  1312. else
  1313. {
  1314. return self :: COMPLEX($logR, $t, $parsedComplex['suffix']);
  1315. }
  1316. } // function IMLN()
  1317. /**
  1318. * IMLOG10
  1319. *
  1320. * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format.
  1321. *
  1322. * @param string $complexNumber
  1323. * @return string
  1324. */
  1325. public static function IMLOG10($complexNumber)
  1326. {
  1327. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1328. $parsedComplex = self :: _parseComplex($complexNumber);
  1329. if (! is_array($parsedComplex))
  1330. {
  1331. return $parsedComplex;
  1332. }
  1333. if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0))
  1334. {
  1335. return PHPExcel_Calculation_Functions :: NaN();
  1336. }
  1337. elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0))
  1338. {
  1339. return log10($parsedComplex['real']);
  1340. }
  1341. return self :: IMPRODUCT(log10(EULER), self :: IMLN($complexNumber));
  1342. } // function IMLOG10()
  1343. /**
  1344. * IMLOG2
  1345. *
  1346. * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format.
  1347. *
  1348. * @param string $complexNumber
  1349. * @return string
  1350. */
  1351. public static function IMLOG2($complexNumber)
  1352. {
  1353. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1354. $parsedComplex = self :: _parseComplex($complexNumber);
  1355. if (! is_array($parsedComplex))
  1356. {
  1357. return $parsedComplex;
  1358. }
  1359. if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0))
  1360. {
  1361. return PHPExcel_Calculation_Functions :: NaN();
  1362. }
  1363. elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0))
  1364. {
  1365. return log($parsedComplex['real'], 2);
  1366. }
  1367. return self :: IMPRODUCT(log(EULER, 2), self :: IMLN($complexNumber));
  1368. } // function IMLOG2()
  1369. /**
  1370. * IMEXP
  1371. *
  1372. * Returns the exponential of a complex number in x + yi or x + yj text format.
  1373. *
  1374. * @param string $complexNumber
  1375. * @return string
  1376. */
  1377. public static function IMEXP($complexNumber)
  1378. {
  1379. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1380. $parsedComplex = self :: _parseComplex($complexNumber);
  1381. if (! is_array($parsedComplex))
  1382. {
  1383. return $parsedComplex;
  1384. }
  1385. if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0))
  1386. {
  1387. return '1';
  1388. }
  1389. $e = exp($parsedComplex['real']);
  1390. $eX = $e * cos($parsedComplex['imaginary']);
  1391. $eY = $e * sin($parsedComplex['imaginary']);
  1392. if ($parsedComplex['suffix'] == '')
  1393. {
  1394. return self :: COMPLEX($eX, $eY);
  1395. }
  1396. else
  1397. {
  1398. return self :: COMPLEX($eX, $eY, $parsedComplex['suffix']);
  1399. }
  1400. } // function IMEXP()
  1401. /**
  1402. * IMPOWER
  1403. *
  1404. * Returns a complex number in x + yi or x + yj text format raised to a power.
  1405. *
  1406. * @param string $complexNumber
  1407. * @return string
  1408. */
  1409. public static function IMPOWER($complexNumber, $realNumber)
  1410. {
  1411. $complexNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber);
  1412. $realNumber = PHPExcel_Calculation_Functions :: flattenSingleValue($realNumber);
  1413. if (! is_numeric($realNumber))
  1414. {
  1415. return PHPExcel_Calculation_Functions :: VALUE();
  1416. }
  1417. $parsedComplex = self :: _parseComplex($complexNumber);
  1418. if (! is_array($parsedComplex))
  1419. {
  1420. return $parsedComplex;
  1421. }
  1422. $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']));
  1423. $rPower = pow($r, $realNumber);
  1424. $theta = self :: IMARGUMENT($complexNumber) * $realNumber;
  1425. if ($theta == 0)
  1426. {
  1427. return 1;
  1428. }
  1429. elseif ($parsedComplex['imaginary'] == 0.0)
  1430. {
  1431. return self :: COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']);
  1432. }
  1433. else
  1434. {
  1435. return self :: COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']);
  1436. }
  1437. } // function IMPOWER()
  1438. /**
  1439. * IMDIV
  1440. *
  1441. * Returns the quotient of two complex numbers in x + yi or x + yj text format.
  1442. *
  1443. * @param string $complexDividend
  1444. * @param string $complexDivisor
  1445. * @return real
  1446. */
  1447. public static function IMDIV($complexDividend, $complexDivisor)
  1448. {
  1449. $complexDividend = PHPExcel_Calculation_Functions :: flattenSingleValue($complexDividend);
  1450. $complexDivisor = PHPExcel_Calculation_Functions :: flattenSingleValue($complexDivisor);
  1451. $parsedComplexDividend = self :: _parseComplex($complexDividend);
  1452. if (! is_array($parsedComplexDividend))
  1453. {
  1454. return $parsedComplexDividend;
  1455. }
  1456. $parsedComplexDivisor = self :: _parseComplex($complexDivisor);
  1457. if (! is_array($parsedComplexDivisor))
  1458. {
  1459. return $parsedComplexDividend;
  1460. }
  1461. if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') && ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix']))
  1462. {
  1463. return PHPExcel_Calculation_Functions :: NaN();
  1464. }
  1465. if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == ''))
  1466. {
  1467. $parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix'];
  1468. }
  1469. $d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']);
  1470. $d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']);
  1471. $d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']);
  1472. $r = $d1 / $d3;
  1473. $i = $d2 / $d3;
  1474. if ($i > 0.0)
  1475. {
  1476. return self :: _cleanComplex($r . '+' . $i . $parsedComplexDivisor['suffix']);
  1477. }
  1478. elseif ($i < 0.0)
  1479. {
  1480. return self :: _cleanComplex($r . $i . $parsedComplexDivisor['suffix']);
  1481. }
  1482. else
  1483. {
  1484. return $r;
  1485. }
  1486. } // function IMDIV()
  1487. /**
  1488. * IMSUB
  1489. *
  1490. * Returns the difference of two complex numbers in x + yi or x + yj text format.
  1491. *
  1492. * @param string $complexNumber1
  1493. * @param string $complexNumber2
  1494. * @return real
  1495. */
  1496. public static function IMSUB($complexNumber1, $complexNumber2)
  1497. {
  1498. $complexNumber1 = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber1);
  1499. $complexNumber2 = PHPExcel_Calculation_Functions :: flattenSingleValue($complexNumber2);
  1500. $parsedComplex1 = self :: _parseComplex($complexNumber1);
  1501. if (! is_array($parsedComplex1))
  1502. {
  1503. return $parsedComplex1;
  1504. }
  1505. $parsedComplex2 = self :: _parseComplex($complexNumber2);
  1506. if (! is_array($parsedComplex2))
  1507. {
  1508. return $parsedComplex2;
  1509. }
  1510. if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) && ($parsedComplex1['suffix'] != $parsedComplex2['suffix']))
  1511. {
  1512. return PHPExcel_Calculation_Functions :: NaN();
  1513. }
  1514. elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != ''))
  1515. {
  1516. $parsedComplex1['suffix'] = $parsedComplex2['suffix'];
  1517. }
  1518. $d1 = $parsedComplex1['real'] - $parsedComplex2['real'];
  1519. $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary'];
  1520. return self :: COMPLEX($d1, $d2, $parsedComplex1['suffix']);
  1521. } // function IMSUB()
  1522. /**
  1523. * IMSUM
  1524. *
  1525. * Returns the sum of two or more complex numbers in x + yi or x + yj text format.
  1526. *
  1527. * @param array of mixed Data Series
  1528. * @return real
  1529. */
  1530. public static function IMSUM()
  1531. {
  1532. // Return value
  1533. $returnValue = self :: _parseComplex('0');
  1534. $activeSuffix = '';
  1535. // Loop through the arguments
  1536. $aArgs = PHPExcel_Calculation_Functions :: flattenArray(func_get_args());
  1537. foreach ($aArgs as $arg)
  1538. {
  1539. $parsedComplex = self :: _parseComplex($arg);
  1540. if (! is_array($parsedComplex))
  1541. {
  1542. return $parsedComplex;
  1543. }
  1544. if ($activeSuffix == '')
  1545. {
  1546. $activeSuffix = $parsedComplex['suffix'];
  1547. }
  1548. elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix']))
  1549. {
  1550. return PHPExcel_Calculation_Functions :: VALUE();
  1551. }
  1552. $returnValue['real'] += $parsedComplex['real'];
  1553. $returnValue['imaginary'] += $parsedComplex['imaginary'];
  1554. }
  1555. if ($returnValue['imaginary'] == 0.0)
  1556. {
  1557. $activeSuffix = '';
  1558. }
  1559. return self :: COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix);
  1560. } // function IMSUM()
  1561. /**
  1562. * IMPRODUCT
  1563. *
  1564. * Returns the product of two or more complex numbers in x + yi or x + yj text format.
  1565. *
  1566. * @param array of mixed Data Series
  1567. * @return real
  1568. */
  1569. public static function IMPRODUCT()
  1570. {
  1571. // Return value
  1572. $returnValue = self :: _parseComplex('1');
  1573. $activeSuffix = '';
  1574. // Loop through the arguments
  1575. $aArgs = PHPExcel_Calculation_Functions :: flattenArray(func_get_args());
  1576. foreach ($aArgs as $arg)
  1577. {
  1578. $parsedComplex = self :: _parseComplex($arg);
  1579. if (! is_array($parsedComplex))
  1580. {
  1581. return $parsedComplex;
  1582. }
  1583. $workValue = $returnValue;
  1584. if (($parsedComplex['suffix'] != '') && ($activeSuffix == ''))
  1585. {
  1586. $activeSuffix = $parsedComplex['suffix'];
  1587. }
  1588. elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix']))
  1589. {
  1590. return PHPExcel_Calculation_Functions :: NaN();
  1591. }
  1592. $returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']);
  1593. $returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']);
  1594. }
  1595. if ($returnValue['imaginary'] == 0.0)
  1596. {
  1597. $activeSuffix = '';
  1598. }
  1599. return self :: COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix);
  1600. } // function IMPRODUCT()
  1601. /**
  1602. * DELTA
  1603. *
  1604. * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise.
  1605. *
  1606. * @param float $a
  1607. * @param float $b
  1608. * @return int
  1609. */
  1610. public static function DELTA($a, $b = 0)
  1611. {
  1612. $a = PHPExcel_Calculation_Functions :: flattenSingleValue($a);
  1613. $b = PHPExcel_Calculation_Functions :: flattenSingleValue($b);
  1614. return (int) ($a == $b);
  1615. } // function DELTA()
  1616. /**
  1617. * GESTEP
  1618. *
  1619. * Returns 1 if number = step; returns 0 (zero) otherwise
  1620. *
  1621. * @param float $number
  1622. * @param float $step
  1623. * @return int
  1624. */
  1625. public static function GESTEP($number, $step = 0)
  1626. {
  1627. $number = PHPExcel_Calculation_Functions :: flattenSingleValue($number);
  1628. $step = PHPExcel_Calculation_Functions :: flattenSingleValue($step);
  1629. return (int) ($number >= $step);
  1630. } // function GESTEP()
  1631. //
  1632. // Private method to calculate the erf value
  1633. //
  1634. private static $_two_sqrtpi = 1.128379167095512574;
  1635. public static function _erfVal($x)
  1636. {
  1637. if (abs($x) > 2.2)
  1638. {
  1639. return 1 - self :: _erfcVal($x);
  1640. }
  1641. $sum = $term = $x;
  1642. $xsqr = ($x * $x);
  1643. $j = 1;
  1644. do
  1645. {
  1646. $term *= $xsqr / $j;
  1647. $sum -= $term / (2 * $j + 1);
  1648. ++ $j;
  1649. $term *= $xsqr / $j;
  1650. $sum += $term / (2 * $j + 1);
  1651. ++ $j;
  1652. if ($sum == 0.0)
  1653. {
  1654. break;
  1655. }
  1656. }
  1657. while (abs($term / $sum) > PRECISION);
  1658. return self :: $_two_sqrtpi * $sum;
  1659. } // function _erfVal()
  1660. /**
  1661. * ERF
  1662. *
  1663. * Returns the error function integrated between lower_limit and upper_limit
  1664. *
  1665. * @param float $lower lower bound for integrating ERF
  1666. * @param float $upper upper bound for integrating ERF.
  1667. * If omitted, ERF integrates between zero and lower_limit
  1668. * @return int
  1669. */
  1670. public static function ERF($lower, $upper = null)
  1671. {
  1672. $lower = PHPExcel_Calculation_Functions :: flattenSingleValue($lower);
  1673. $upper = PHPExcel_Calculation_Functions :: flattenSingleValue($upper);
  1674. if (is_numeric($lower))
  1675. {
  1676. if ($lower < 0)
  1677. {
  1678. return PHPExcel_Calculation_Functions :: NaN();
  1679. }
  1680. if (is_null($upper))
  1681. {
  1682. return self :: _erfVal($lower);
  1683. }
  1684. if (is_numeric($upper))
  1685. {
  1686. if ($upper < 0)
  1687. {
  1688. return PHPExcel_Calculation_Functions :: NaN();
  1689. }
  1690. return self :: _erfVal($upper) - self :: _erfVal($lower);
  1691. }
  1692. }
  1693. return PHPExcel_Calculation_Functions :: VALUE();
  1694. } // function ERF()
  1695. //
  1696. // Private method to calculate the erfc value
  1697. //
  1698. private static $_one_sqrtpi = 0.564189583547756287;
  1699. private static function _erfcVal($x)
  1700. {
  1701. if (abs($x) < 2.2)
  1702. {
  1703. return 1 - self :: _erfVal($x);
  1704. }
  1705. if ($x < 0)
  1706. {
  1707. return 2 - self :: ERFC(- $x);
  1708. }
  1709. $a = $n = 1;
  1710. $b = $c = $x;
  1711. $d = ($x * $x) + 0.5;
  1712. $q1 = $q2 = $b / $d;
  1713. $t = 0;
  1714. do
  1715. {
  1716. $t = $a * $n + $b * $x;
  1717. $a = $b;
  1718. $b = $t;
  1719. $t = $c * $n + $d * $x;
  1720. $c = $d;
  1721. $d = $t;
  1722. $n += 0.5;
  1723. $q1 = $q2;
  1724. $q2 = $b / $d;
  1725. }
  1726. while ((abs($q1 - $q2) / $q2) > PRECISION);
  1727. return self :: $_one_sqrtpi * exp(- $x * $x) * $q2;
  1728. } // function _erfcVal()
  1729. /**
  1730. * ERFC
  1731. *
  1732. * Returns the complementary ERF function integrated between x and infinity
  1733. *
  1734. * @param float $x The lower bound for integrating ERF
  1735. * @return int
  1736. */
  1737. public static function ERFC($x)
  1738. {
  1739. $x = PHPExcel_Calculation_Functions :: flattenSingleValue($x);
  1740. if (is_numeric($x))
  1741. {
  1742. if ($x < 0)
  1743. {
  1744. return PHPExcel_Calculation_Functions :: NaN();
  1745. }
  1746. return self :: _erfcVal($x);
  1747. }
  1748. return PHPExcel_Calculation_Functions :: VALUE();
  1749. } // function ERFC()
  1750. /**
  1751. * getConversionGroups
  1752. *
  1753. * @return array
  1754. */
  1755. public static function getConversionGroups()
  1756. {
  1757. $conversionGroups = array();
  1758. foreach (self :: $_conversionUnits as $conversionUnit)
  1759. {
  1760. $conversionGroups[] = $conversionUnit['Group'];
  1761. }
  1762. return array_merge(array_unique($conversionGroups));
  1763. } // function getConversionGroups()
  1764. /**
  1765. * getConversionGroupUnits
  1766. *
  1767. * @return array
  1768. */
  1769. public static function getConversionGroupUnits($group = NULL)
  1770. {
  1771. $conversionGroups = array();
  1772. foreach (self :: $_conversionUnits as $conversionUnit => $conversionGroup)
  1773. {
  1774. if ((is_null($group)) || ($conversionGroup['Group'] == $group))
  1775. {
  1776. $conversionGroups[$conversionGroup['Group']][] = $conversionUnit;
  1777. }
  1778. }
  1779. return $conversionGroups;
  1780. } // function getConversionGroupUnits()
  1781. /**
  1782. * getConversionGroupUnitDetails
  1783. *
  1784. * @return array
  1785. */
  1786. public static function getConversionGroupUnitDetails($group = NULL)
  1787. {
  1788. $conversionGroups = array();
  1789. foreach (self :: $_conversionUnits as $conversionUnit => $conversionGroup)
  1790. {
  1791. if ((is_null($group)) || ($conversionGroup['Group'] == $group))
  1792. {
  1793. $conversionGroups[$conversionGroup['Group']][] = array('unit' => $conversionUnit,
  1794. 'description' => $conversionGroup['Unit Name']);
  1795. }
  1796. }
  1797. return $conversionGroups;
  1798. } // function getConversionGroupUnitDetails()
  1799. /**
  1800. * getConversionGroups
  1801. *
  1802. * @return array
  1803. */
  1804. public static function getConversionMultipliers()
  1805. {
  1806. return self :: $_conversionMultipliers;
  1807. } // function getConversionGroups()
  1808. /**
  1809. * CONVERTUOM
  1810. *
  1811. * @param float $value
  1812. * @param string $fromUOM
  1813. * @param string $toUOM
  1814. * @return float
  1815. */
  1816. public static function CONVERTUOM($value, $fromUOM, $toUOM)
  1817. {
  1818. $value = PHPExcel_Calculation_Functions :: flattenSingleValue($value);
  1819. $fromUOM = PHPExcel_Calculation_Functions :: flattenSingleValue($fromUOM);
  1820. $toUOM = PHPExcel_Calculation_Functions :: flattenSingleValue($toUOM);
  1821. if (! is_numeric($value))
  1822. {
  1823. return PHPExcel_Calculation_Functions :: VALUE();
  1824. }
  1825. $fromMultiplier = 1;
  1826. if (isset(self :: $_conversionUnits[$fromUOM]))
  1827. {
  1828. $unitGroup1 = self :: $_conversionUnits[$fromUOM]['Group'];
  1829. }
  1830. else
  1831. {
  1832. $fromMultiplier = substr($fromUOM, 0, 1);
  1833. $fromUOM = substr($fromUOM, 1);
  1834. if (isset(self :: $_conversionMultipliers[$fromMultiplier]))
  1835. {
  1836. $fromMultiplier = self :: $_conversionMultipliers[$fromMultiplier]['multiplier'];
  1837. }
  1838. else
  1839. {
  1840. return PHPExcel_Calculation_Functions :: NA();
  1841. }
  1842. if ((isset(self :: $_conversionUnits[$fromUOM])) && (self :: $_conversionUnits[$fromUOM]['AllowPrefix']))
  1843. {
  1844. $unitGroup1 = self :: $_conversionUnits[$fromUOM]['Group'];
  1845. }
  1846. else
  1847. {
  1848. return PHPExcel_Calculation_Functions :: NA();
  1849. }
  1850. }
  1851. $value *= $fromMultiplier;
  1852. $toMultiplier = 1;
  1853. if (isset(self :: $_conversionUnits[$toUOM]))
  1854. {
  1855. $unitGroup2 = self :: $_conversionUnits[$toUOM]['Group'];
  1856. }
  1857. else
  1858. {
  1859. $toMultiplier = substr($toUOM, 0, 1);
  1860. $toUOM = substr($toUOM, 1);
  1861. if (isset(self :: $_conversionMultipliers[$toMultiplier]))
  1862. {
  1863. $toMultiplier = self :: $_conversionMultipliers[$toMultiplier]['multiplier'];
  1864. }
  1865. else
  1866. {
  1867. return PHPExcel_Calculation_Functions :: NA();
  1868. }
  1869. if ((isset(self :: $_conversionUnits[$toUOM])) && (self :: $_conversionUnits[$toUOM]['AllowPrefix']))
  1870. {
  1871. $unitGroup2 = self :: $_conversionUnits[$toUOM]['Group'];
  1872. }
  1873. else
  1874. {
  1875. return PHPExcel_Calculation_Functions :: NA();
  1876. }
  1877. }
  1878. if ($unitGroup1 != $unitGroup2)
  1879. {
  1880. return PHPExcel_Calculation_Functions :: NA();
  1881. }
  1882. if ($fromUOM == $toUOM)
  1883. {
  1884. return 1.0;
  1885. }
  1886. elseif ($unitGroup1 == 'Temperature')
  1887. {
  1888. if (($fromUOM == 'F') || ($fromUOM == 'fah'))
  1889. {
  1890. if (($toUOM == 'F') || ($toUOM == 'fah'))
  1891. {
  1892. return 1.0;
  1893. }
  1894. else
  1895. {
  1896. $value = (($value - 32) / 1.8);
  1897. if (($toUOM == 'K') || ($toUOM == 'kel'))
  1898. {
  1899. $value += 273.15;
  1900. }
  1901. return $value;
  1902. }
  1903. }
  1904. elseif ((($fromUOM == 'K') || ($fromUOM == 'kel')) && (($toUOM == 'K') || ($toUOM == 'kel')))
  1905. {
  1906. return 1.0;
  1907. }
  1908. elseif ((($fromUOM == 'C') || ($fromUOM == 'cel')) && (($toUOM == 'C') || ($toUOM == 'cel')))
  1909. {
  1910. return 1.0;
  1911. }
  1912. if (($toUOM == 'F') || ($toUOM == 'fah'))
  1913. {
  1914. if (($fromUOM == 'K') || ($fromUOM == 'kel'))
  1915. {
  1916. $value -= 273.15;
  1917. }
  1918. return ($value * 1.8) + 32;
  1919. }
  1920. if (($toUOM == 'C') || ($toUOM == 'cel'))
  1921. {
  1922. return $value - 273.15;
  1923. }
  1924. return $value + 273.15;
  1925. }
  1926. return ($value * self :: $_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier;
  1927. } // function CONVERTUOM()
  1928. } // class PHPExcel_Calculation_Engineering