--- /dev/null
+package org.apache.poi.ss.formula.functions;\r
+\r
+import org.apache.poi.ss.formula.eval.*;\r
+\r
+/**\r
+ * Implementation for Excel COMPLEX () function.<p/>\r
+ * <p/>\r
+ * <b>Syntax</b>:<br/> <b>COMPLEX </b>(<b>real_num</b>,<b>i_num</b>,<b>suffix </b> )<br/>\r
+ * <p/>\r
+ * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj.\r
+ * <p/>\r
+ * <p/>\r
+ * All complex number functions accept "i" and "j" for suffix, but neither "I" nor "J".\r
+ * Using uppercase results in the #VALUE! error value. All functions that accept two\r
+ * or more complex numbers require that all suffixes match.\r
+ * <p/>\r
+ * <b>real_num</b> The real coefficient of the complex number.\r
+ * If this argument is nonnumeric, this function returns the #VALUE! error value.\r
+ * <p/>\r
+ * <p/>\r
+ * <b>i_num</b> The imaginary coefficient of the complex number.\r
+ * If this argument is nonnumeric, this function returns the #VALUE! error value.\r
+ * <p/>\r
+ * <p/>\r
+ * <b>suffix</b> The suffix for the imaginary component of the complex number.\r
+ * <ul>\r
+ * <li>If omitted, suffix is assumed to be "i".</li>\r
+ * <li>If suffix is neither "i" nor "j", COMPLEX returns the #VALUE! error value.</li>\r
+ * </ul>\r
+ *\r
+ * @author cedric dot walter @ gmail dot com\r
+ */\r
+public class Complex extends Var2or3ArgFunction {\r
+\r
+ public static final String DEFAULT_SUFFIX = "i";\r
+ public static final String SUPPORTED_SUFFIX = "j";\r
+\r
+ @Override\r
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval real_num, ValueEval i_num) {\r
+ return this.evaluate(srcRowIndex, srcColumnIndex, real_num, i_num, new StringEval(DEFAULT_SUFFIX));\r
+ }\r
+\r
+ @Override\r
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval real_num, ValueEval i_num, ValueEval suffix) {\r
+ ValueEval veText1;\r
+ try {\r
+ veText1 = OperandResolver.getSingleValue(real_num, srcRowIndex, srcColumnIndex);\r
+ } catch (EvaluationException e) {\r
+ return e.getErrorEval();\r
+ }\r
+ double realNum = 0;\r
+ try {\r
+ realNum = OperandResolver.coerceValueToDouble(veText1);\r
+ } catch (EvaluationException e) {\r
+ return ErrorEval.VALUE_INVALID;\r
+ }\r
+\r
+ ValueEval veINum;\r
+ try {\r
+ veINum = OperandResolver.getSingleValue(i_num, srcRowIndex, srcColumnIndex);\r
+ } catch (EvaluationException e) {\r
+ return e.getErrorEval();\r
+ }\r
+ double realINum = 0;\r
+ try {\r
+ realINum = OperandResolver.coerceValueToDouble(veINum);\r
+ } catch (EvaluationException e) {\r
+ return ErrorEval.VALUE_INVALID;\r
+ }\r
+\r
+ String suffixValue = OperandResolver.coerceValueToString(suffix);\r
+ if (suffixValue.isEmpty()) {\r
+ suffixValue = DEFAULT_SUFFIX;\r
+ }\r
+ if (suffixValue.equals(DEFAULT_SUFFIX.toUpperCase()) || suffixValue.equals(SUPPORTED_SUFFIX.toUpperCase())) {\r
+ return ErrorEval.VALUE_INVALID;\r
+ }\r
+ if (!(suffixValue.equals(DEFAULT_SUFFIX) || suffixValue.equals(SUPPORTED_SUFFIX))) {\r
+ return ErrorEval.VALUE_INVALID;\r
+ }\r
+\r
+ StringBuffer strb = new StringBuffer("");\r
+ if (realNum != 0) {\r
+ if (isDoubleAnInt(realNum)) {\r
+ strb.append(new Double(realNum).intValue());\r
+ } else {\r
+ strb.append(realNum);\r
+ }\r
+ }\r
+ if (realINum != 0) {\r
+ if (strb.length() != 0) {\r
+ if (realINum > 0) {\r
+ strb.append("+");\r
+ }\r
+ }\r
+\r
+ if (realINum != 1 && realINum != -1) {\r
+ if (isDoubleAnInt(realINum)) {\r
+ strb.append(new Double(realINum).intValue());\r
+ } else {\r
+ strb.append(realINum);\r
+ }\r
+ }\r
+\r
+ strb.append(suffixValue);\r
+ }\r
+\r
+ return new StringEval(strb.toString());\r
+ }\r
+\r
+ /**\r
+ * @param number\r
+ * @return\r
+ */\r
+ private boolean isDoubleAnInt(double number) {\r
+ return (number == Math.floor(number)) && !Double.isInfinite(number);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.apache.poi.ss.formula.functions;\r
+\r
+import org.apache.poi.ss.formula.eval.ValueEval;\r
+\r
+\r
+import org.apache.poi.ss.formula.eval.*;\r
+\r
+/**\r
+ * <p>Implementation for Excel QUOTIENT () function.<p/>\r
+ * <p>\r
+ * <b>Syntax</b>:<br/> <b>QUOTIENT</b>(<b>Numerator</b>,<b>Denominator</b>)<br/>\r
+ * <p/>\r
+ * <p>\r
+ * Numerator is the dividend.\r
+ * Denominator is the divisor.\r
+ *\r
+ * Returns the integer portion of a division. Use this function when you want to discard the remainder of a division.\r
+ * <p/>\r
+ *\r
+ * If either enumerator/denominator is non numeric, QUOTIENT returns the #VALUE! error value.\r
+ * If denominator is equals to zero, QUOTIENT returns the #DIV/0! error value.\r
+ *\r
+ * @author cedric dot walter @ gmail dot com\r
+ */\r
+public class Quotient extends Fixed2ArgFunction {\r
+ @Override\r
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval venumerator, ValueEval vedenominator) {\r
+\r
+ double enumerator = 0;\r
+ try {\r
+ enumerator = OperandResolver.coerceValueToDouble(venumerator);\r
+ } catch (EvaluationException e) {\r
+ return ErrorEval.VALUE_INVALID;\r
+ }\r
+\r
+ double denominator = 0;\r
+ try {\r
+ denominator = OperandResolver.coerceValueToDouble(vedenominator);\r
+ } catch (EvaluationException e) {\r
+ return ErrorEval.VALUE_INVALID;\r
+ }\r
+\r
+ if (denominator == 0) {\r
+ return ErrorEval.DIV_ZERO;\r
+ }\r
+\r
+ return new StringEval(String.valueOf((int)(enumerator / denominator)));\r
+ }\r
+}\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.ss.formula.functions;\r
+\r
+import junit.framework.TestCase;\r
+import org.apache.poi.ss.formula.eval.ErrorEval;\r
+import org.apache.poi.ss.formula.eval.StringEval;\r
+import org.apache.poi.ss.formula.eval.ValueEval;\r
+\r
+/**\r
+ * Tests for {@link Complex}\r
+ *\r
+ * @author cedric dot walter @ gmail dot com\r
+ */\r
+public class TestComplex extends TestCase\r
+{\r
+ private static ValueEval invokeValue(String real_num, String i_num, String suffix) {\r
+ ValueEval[] args = new ValueEval[]{new StringEval(real_num), new StringEval(i_num), new StringEval(suffix)};\r
+ return new Complex().evaluate(args, -1, -1);\r
+ }\r
+\r
+ private static void confirmValue(String msg, String real_num, String i_num, String suffix, String expected) {\r
+ ValueEval result = invokeValue(real_num, i_num, suffix);\r
+ assertEquals(StringEval.class, result.getClass());\r
+ assertEquals(msg, expected, ((StringEval) result).getStringValue());\r
+ }\r
+\r
+ private static void confirmValueError(String msg, String real_num, String i_num, String suffix, ErrorEval numError) {\r
+ ValueEval result = invokeValue(real_num, i_num, suffix);\r
+ assertEquals(ErrorEval.class, result.getClass());\r
+ assertEquals(msg, numError, result);\r
+ }\r
+\r
+ public void testBasic() {\r
+ confirmValue("Complex number with 3 and 4 as the real and imaginary coefficients (3 + 4i)", "3","4", "", "3+4i");\r
+ confirmValue("Complex number with 3 and 4 as the real and imaginary coefficients, and j as the suffix (3 + 4j)", "3","4", "j", "3+4j");\r
+\r
+ confirmValue("Complex number with 0 and 1 as the real and imaginary coefficients (i)", "0","1", "", "i");\r
+ confirmValue("Complex number with 1 and 0 as the real and imaginary coefficients (1)", "1","0", "", "1");\r
+\r
+ confirmValue("Complex number with 2 and 3 as the real and imaginary coefficients (2 + 3i)", "2","3", "", "2+3i");\r
+ confirmValue("Complex number with -2 and -3 as the real and imaginary coefficients (-2-3i)", "-2","-3", "", "-2-3i");\r
+\r
+ confirmValue("Complex number with -2 and -3 as the real and imaginary coefficients (-0.5-3.2i)", "-0.5","-3.2", "", "-0.5-3.2i");\r
+ }\r
+\r
+ public void testErrors() {\r
+ confirmValueError("argument is nonnumeric", "ABCD", "","", ErrorEval.VALUE_INVALID);\r
+ confirmValueError("argument is nonnumeric", "1", "ABCD","", ErrorEval.VALUE_INVALID);\r
+ confirmValueError("f suffix is neither \"i\" nor \"j\"", "1", "1","k", ErrorEval.VALUE_INVALID);\r
+\r
+ confirmValueError("never use \"I\" ", "1", "1","I", ErrorEval.VALUE_INVALID);\r
+ confirmValueError("never use \"J\" ", "1", "1","J", ErrorEval.VALUE_INVALID);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.ss.formula.functions;\r
+\r
+import junit.framework.TestCase;\r
+import org.apache.poi.ss.formula.eval.ErrorEval;\r
+import org.apache.poi.ss.formula.eval.StringEval;\r
+import org.apache.poi.ss.formula.eval.ValueEval;\r
+\r
+/**\r
+ * Tests for {@link Quotient}\r
+ *\r
+ * @author cedric dot walter @ gmail dot com\r
+ */\r
+public class TestQuotient extends TestCase {\r
+ private static ValueEval invokeValue(String numerator, String denominator) {\r
+ ValueEval[] args = new ValueEval[]{new StringEval(numerator), new StringEval(denominator)};\r
+ return new Quotient().evaluate(args, -1, -1);\r
+ }\r
+\r
+ private static void confirmValue(String msg, String numerator, String denominator, String expected) {\r
+ ValueEval result = invokeValue(numerator, denominator);\r
+ assertEquals(StringEval.class, result.getClass());\r
+ assertEquals(msg, expected, ((StringEval) result).getStringValue());\r
+ }\r
+\r
+ private static void confirmValueError(String msg, String numerator, String denominator, ErrorEval numError) {\r
+ ValueEval result = invokeValue(numerator, denominator);\r
+ assertEquals(ErrorEval.class, result.getClass());\r
+ assertEquals(msg, numError, result);\r
+ }\r
+\r
+ public void testBasic() {\r
+ confirmValue("Integer portion of 5/2 (2)", "5", "2", "2");\r
+ confirmValue("Integer portion of 4.5/3.1 (1)", "4.5", "3.1", "1");\r
+\r
+ confirmValue("Integer portion of -10/3 (-3)", "-10", "3", "-3");\r
+ confirmValue("Integer portion of -5.5/2 (-2)", "-5.5", "2", "-2");\r
+\r
+ confirmValue("Integer portion of Pi/Avogadro (0)", "3.14159", "6.02214179E+23", "0");\r
+ }\r
+\r
+ public void testErrors() {\r
+ confirmValueError("numerator is nonnumeric", "ABCD", "", ErrorEval.VALUE_INVALID);\r
+ confirmValueError("denominator is nonnumeric", "", "ABCD", ErrorEval.VALUE_INVALID);\r
+\r
+ confirmValueError("denominator is nonnumeric", "3.14159", "0", ErrorEval.DIV_ZERO);\r
+ }\r
+}
\ No newline at end of file