Browse Source

#65 fn: CEILING.PRECISE, COMBIN, COMBINA, COS, COSH, COT, COTH, CSC

xuri 5 years ago
parent
commit
5c82f2269d
2 changed files with 312 additions and 68 deletions
  1. 252 67
      calc.go
  2. 60 1
      calc_test.go

+ 252 - 67
calc.go

@@ -504,8 +504,7 @@ func (fn *formulaFuncs) ABS(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Abs(val))
@@ -524,8 +523,7 @@ func (fn *formulaFuncs) ACOS(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Acos(val))
@@ -543,8 +541,7 @@ func (fn *formulaFuncs) ACOSH(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Acosh(val))
@@ -563,8 +560,7 @@ func (fn *formulaFuncs) ACOT(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Pi/2-math.Atan(val))
@@ -582,8 +578,7 @@ func (fn *formulaFuncs) ACOTH(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Atanh(1/val))
@@ -652,8 +647,7 @@ func (fn *formulaFuncs) ASIN(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Asin(val))
@@ -671,8 +665,7 @@ func (fn *formulaFuncs) ASINH(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Asinh(val))
@@ -691,8 +684,7 @@ func (fn *formulaFuncs) ATAN(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Atan(val))
@@ -710,8 +702,7 @@ func (fn *formulaFuncs) ATANH(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Atanh(val))
@@ -730,12 +721,10 @@ func (fn *formulaFuncs) ATAN2(argsList *list.List) (result string, err error) {
 		return
 	}
 	var x, y float64
-	x, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if x, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
-	y, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if y, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	result = fmt.Sprintf("%g", math.Atan2(x, y))
@@ -777,12 +766,10 @@ func (fn *formulaFuncs) BASE(argsList *list.List) (result string, err error) {
 	}
 	var number float64
 	var radix, minLength int
-	number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
-	radix, err = strconv.Atoi(argsList.Front().Next().Value.(efp.Token).TValue)
-	if err != nil {
+	if radix, err = strconv.Atoi(argsList.Front().Next().Value.(efp.Token).TValue); err != nil {
 		return
 	}
 	if radix < 2 || radix > 36 {
@@ -790,8 +777,7 @@ func (fn *formulaFuncs) BASE(argsList *list.List) (result string, err error) {
 		return
 	}
 	if argsList.Len() > 2 {
-		minLength, err = strconv.Atoi(argsList.Back().Value.(efp.Token).TValue)
-		if err != nil {
+		if minLength, err = strconv.Atoi(argsList.Back().Value.(efp.Token).TValue); err != nil {
 			return
 		}
 	}
@@ -817,18 +803,15 @@ func (fn *formulaFuncs) CEILING(argsList *list.List) (result string, err error)
 		err = errors.New("CEILING allows at most 2 arguments")
 		return
 	}
-	var number, significance float64
-	number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	var number, significance float64 = 0, 1
+	if number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
-	significance = 1
 	if number < 0 {
 		significance = -1
 	}
 	if argsList.Len() > 1 {
-		significance, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
-		if err != nil {
+		if significance, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
 			return
 		}
 	}
@@ -863,16 +846,14 @@ func (fn *formulaFuncs) CEILINGMATH(argsList *list.List) (result string, err err
 		return
 	}
 	var number, significance, mode float64 = 0, 1, 1
-	number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	if number < 0 {
 		significance = -1
 	}
 	if argsList.Len() > 1 {
-		significance, err = strconv.ParseFloat(argsList.Front().Next().Value.(efp.Token).TValue, 64)
-		if err != nil {
+		if significance, err = strconv.ParseFloat(argsList.Front().Next().Value.(efp.Token).TValue, 64); err != nil {
 			return
 		}
 	}
@@ -881,13 +862,11 @@ func (fn *formulaFuncs) CEILINGMATH(argsList *list.List) (result string, err err
 		return
 	}
 	if argsList.Len() > 2 {
-		mode, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
-		if err != nil {
+		if mode, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
 			return
 		}
 	}
 	val, res := math.Modf(number / significance)
-	_, _ = res, mode
 	if res != 0 {
 		if number > 0 {
 			val++
@@ -895,11 +874,231 @@ func (fn *formulaFuncs) CEILINGMATH(argsList *list.List) (result string, err err
 			val--
 		}
 	}
+	result = fmt.Sprintf("%g", val*significance)
+	return
+}
 
+// CEILINGPRECISE function rounds a supplied number up (regardless of the
+// number's sign), to the nearest multiple of a given number. The syntax of
+// the function is:
+//
+//   CEILING.PRECISE(number,[significance])
+//
+func (fn *formulaFuncs) CEILINGPRECISE(argsList *list.List) (result string, err error) {
+	if argsList.Len() == 0 {
+		err = errors.New("CEILING.PRECISE requires at least 1 argument")
+		return
+	}
+	if argsList.Len() > 2 {
+		err = errors.New("CEILING.PRECISE allows at most 2 arguments")
+		return
+	}
+	var number, significance float64 = 0, 1
+	if number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	if number < 0 {
+		significance = -1
+	}
+	if argsList.Len() == 1 {
+		result = fmt.Sprintf("%g", math.Ceil(number))
+		return
+	}
+	if argsList.Len() > 1 {
+		if significance, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
+			return
+		}
+		significance = math.Abs(significance)
+		if significance == 0 {
+			result = "0"
+			return
+		}
+	}
+	val, res := math.Modf(number / significance)
+	if res != 0 {
+		if number > 0 {
+			val++
+		}
+	}
 	result = fmt.Sprintf("%g", val*significance)
 	return
 }
 
+// COMBIN function calculates the number of combinations (in any order) of a
+// given number objects from a set. The syntax of the function is:
+//
+//   COMBIN(number,number_chosen)
+//
+func (fn *formulaFuncs) COMBIN(argsList *list.List) (result string, err error) {
+	if argsList.Len() != 2 {
+		err = errors.New("COMBIN requires 2 argument")
+		return
+	}
+	var number, chosen, val float64 = 0, 0, 1
+	if number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	if chosen, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	number, chosen = math.Trunc(number), math.Trunc(chosen)
+	if chosen > number {
+		err = errors.New("COMBIN requires number >= number_chosen")
+		return
+	}
+	if chosen == number || chosen == 0 {
+		result = "1"
+		return
+	}
+	for c := float64(1); c <= chosen; c++ {
+		val *= (number + 1 - c) / c
+	}
+	result = fmt.Sprintf("%g", math.Ceil(val))
+	return
+}
+
+// COMBINA function calculates the number of combinations, with repetitions,
+// of a given number objects from a set. The syntax of the function is:
+//
+//   COMBINA(number,number_chosen)
+//
+func (fn *formulaFuncs) COMBINA(argsList *list.List) (result string, err error) {
+	if argsList.Len() != 2 {
+		err = errors.New("COMBINA requires 2 argument")
+		return
+	}
+	var number, chosen float64
+	if number, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	if chosen, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	number, chosen = math.Trunc(number), math.Trunc(chosen)
+	if number < chosen {
+		err = errors.New("COMBINA requires number > number_chosen")
+		return
+	}
+	if number == 0 {
+		result = "0"
+		return
+	}
+	args := list.New()
+	args.PushBack(efp.Token{
+		TValue:   fmt.Sprintf("%g", number+chosen-1),
+		TType:    efp.TokenTypeOperand,
+		TSubType: efp.TokenSubTypeNumber,
+	})
+	args.PushBack(efp.Token{
+		TValue:   fmt.Sprintf("%g", number-1),
+		TType:    efp.TokenTypeOperand,
+		TSubType: efp.TokenSubTypeNumber,
+	})
+	return fn.COMBIN(args)
+}
+
+// COS function calculates the cosine of a given angle. The syntax of the
+// function is:
+//
+//   COS(number)
+//
+func (fn *formulaFuncs) COS(argsList *list.List) (result string, err error) {
+	if argsList.Len() != 1 {
+		err = errors.New("COS requires 1 numeric arguments")
+		return
+	}
+	var val float64
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	result = fmt.Sprintf("%g", math.Cos(val))
+	return
+}
+
+// COSH function calculates the hyperbolic cosine (cosh) of a supplied number.
+// The syntax of the function is:
+//
+//   COSH(number)
+//
+func (fn *formulaFuncs) COSH(argsList *list.List) (result string, err error) {
+	if argsList.Len() != 1 {
+		err = errors.New("COSH requires 1 numeric arguments")
+		return
+	}
+	var val float64
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	result = fmt.Sprintf("%g", math.Cosh(val))
+	return
+}
+
+// COT function calculates the cotangent of a given angle. The syntax of the
+// function is:
+//
+//   COT(number)
+//
+func (fn *formulaFuncs) COT(argsList *list.List) (result string, err error) {
+	if argsList.Len() != 1 {
+		err = errors.New("COT requires 1 numeric arguments")
+		return
+	}
+	var val float64
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	if val == 0 {
+		err = errors.New(formulaErrorNAME)
+		return
+	}
+	result = fmt.Sprintf("%g", math.Tan(val))
+	return
+}
+
+// COTH function calculates the hyperbolic cotangent (coth) of a supplied
+// angle. The syntax of the function is:
+//
+//   COTH(number)
+//
+func (fn *formulaFuncs) COTH(argsList *list.List) (result string, err error) {
+	if argsList.Len() != 1 {
+		err = errors.New("COTH requires 1 numeric arguments")
+		return
+	}
+	var val float64
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	if val == 0 {
+		err = errors.New(formulaErrorNAME)
+		return
+	}
+	result = fmt.Sprintf("%g", math.Tanh(val))
+	return
+}
+
+// CSC function calculates the cosecant of a given angle. The syntax of the
+// function is:
+//
+//   CSC(number)
+//
+func (fn *formulaFuncs) CSC(argsList *list.List) (result string, err error) {
+	if argsList.Len() != 1 {
+		err = errors.New("CSC requires 1 numeric arguments")
+		return
+	}
+	var val float64
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
+		return
+	}
+	if val == 0 {
+		err = errors.New(formulaErrorNAME)
+		return
+	}
+	result = fmt.Sprintf("%g", 1/math.Sin(val))
+	return
+}
+
 // GCD function returns the greatest common divisor of two or more supplied
 // integers. The syntax of the function is:
 //
@@ -919,8 +1118,7 @@ func (fn *formulaFuncs) GCD(argsList *list.List) (result string, err error) {
 		if token.TValue == "" {
 			continue
 		}
-		val, err = strconv.ParseFloat(token.TValue, 64)
-		if err != nil {
+		if val, err = strconv.ParseFloat(token.TValue, 64); err != nil {
 			return
 		}
 		nums = append(nums, val)
@@ -974,8 +1172,7 @@ func (fn *formulaFuncs) LCM(argsList *list.List) (result string, err error) {
 		if token.TValue == "" {
 			continue
 		}
-		val, err = strconv.ParseFloat(token.TValue, 64)
-		if err != nil {
+		if val, err = strconv.ParseFloat(token.TValue, 64); err != nil {
 			return
 		}
 		nums = append(nums, val)
@@ -1011,12 +1208,10 @@ func (fn *formulaFuncs) POWER(argsList *list.List) (result string, err error) {
 		return
 	}
 	var x, y float64
-	x, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if x, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
-	y, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if y, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	if x == 0 && y == 0 {
@@ -1037,17 +1232,13 @@ func (fn *formulaFuncs) POWER(argsList *list.List) (result string, err error) {
 //    PRODUCT(number1,[number2],...)
 //
 func (fn *formulaFuncs) PRODUCT(argsList *list.List) (result string, err error) {
-	var (
-		val     float64
-		product float64 = 1
-	)
+	var val, product float64 = 0, 1
 	for arg := argsList.Front(); arg != nil; arg = arg.Next() {
 		token := arg.Value.(efp.Token)
 		if token.TValue == "" {
 			continue
 		}
-		val, err = strconv.ParseFloat(token.TValue, 64)
-		if err != nil {
+		if val, err = strconv.ParseFloat(token.TValue, 64); err != nil {
 			return
 		}
 		product = product * val
@@ -1069,8 +1260,7 @@ func (fn *formulaFuncs) SIGN(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	if val < 0 {
@@ -1096,8 +1286,7 @@ func (fn *formulaFuncs) SQRT(argsList *list.List) (result string, err error) {
 		return
 	}
 	var val float64
-	val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if val, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	if val < 0 {
@@ -1114,15 +1303,13 @@ func (fn *formulaFuncs) SQRT(argsList *list.List) (result string, err error) {
 //    SUM(number1,[number2],...)
 //
 func (fn *formulaFuncs) SUM(argsList *list.List) (result string, err error) {
-	var val float64
-	var sum float64
+	var val, sum float64
 	for arg := argsList.Front(); arg != nil; arg = arg.Next() {
 		token := arg.Value.(efp.Token)
 		if token.TValue == "" {
 			continue
 		}
-		val, err = strconv.ParseFloat(token.TValue, 64)
-		if err != nil {
+		if val, err = strconv.ParseFloat(token.TValue, 64); err != nil {
 			return
 		}
 		sum += val
@@ -1142,12 +1329,10 @@ func (fn *formulaFuncs) QUOTIENT(argsList *list.List) (result string, err error)
 		return
 	}
 	var x, y float64
-	x, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if x, err = strconv.ParseFloat(argsList.Front().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
-	y, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64)
-	if err != nil {
+	if y, err = strconv.ParseFloat(argsList.Back().Value.(efp.Token).TValue, 64); err != nil {
 		return
 	}
 	if y == 0 {

+ 60 - 1
calc_test.go

@@ -83,6 +83,44 @@ func TestCalcCellValue(t *testing.T) {
 		"=_xlfn.CEILING.MATH(-15.25,1)":   "-15",
 		"=_xlfn.CEILING.MATH(-15.25,1,1)": "-15", // should be 16
 		"=_xlfn.CEILING.MATH(-15.25,10)":  "-10",
+		// _xlfn.CEILING.PRECISE
+		"=_xlfn.CEILING.PRECISE(22.25,0.1)": "22.3",
+		"=_xlfn.CEILING.PRECISE(22.25,0.5)": "22.5",
+		"=_xlfn.CEILING.PRECISE(22.25,1)":   "23",
+		"=_xlfn.CEILING.PRECISE(22.25)":     "23",
+		"=_xlfn.CEILING.PRECISE(22.25,10)":  "30",
+		"=_xlfn.CEILING.PRECISE(22.25,0)":   "0",
+		"=_xlfn.CEILING.PRECISE(-22.25,1)":  "-22",
+		"=_xlfn.CEILING.PRECISE(-22.25,-1)": "-22",
+		"=_xlfn.CEILING.PRECISE(-22.25,5)":  "-20",
+		// COMBIN
+		"=COMBIN(6,1)": "6",
+		"=COMBIN(6,2)": "15",
+		"=COMBIN(6,3)": "20",
+		"=COMBIN(6,4)": "15",
+		"=COMBIN(6,5)": "6",
+		"=COMBIN(6,6)": "1",
+		// _xlfn.COMBINA
+		"=_xlfn.COMBINA(6,1)": "6",
+		"=_xlfn.COMBINA(6,2)": "21",
+		"=_xlfn.COMBINA(6,3)": "56",
+		"=_xlfn.COMBINA(6,4)": "126",
+		"=_xlfn.COMBINA(6,5)": "252",
+		"=_xlfn.COMBINA(6,6)": "462",
+		// COS
+		"=COS(0.785398163)": "0.707106781467586",
+		"=COS(0)":           "1",
+		// COSH
+		"=COSH(0)":   "1",
+		"=COSH(0.5)": "1.1276259652063807",
+		"=COSH(-2)":  "3.7621956910836314",
+		// _xlfn.COT
+		"_xlfn.COT(0.785398163397448)": "0.9999999999999992",
+		// _xlfn.COTH
+		"_xlfn.COTH(-3.14159265358979)": "-0.9962720762207499",
+		// _xlfn.CSC
+		"_xlfn.CSC(-6)":              "3.5788995472544056",
+		"_xlfn.CSC(1.5707963267949)": "1",
 		// GCD
 		"=GCD(1,5)":      "1",
 		"=GCD(15,10,25)": "5",
@@ -144,7 +182,7 @@ func TestCalcCellValue(t *testing.T) {
 		// _xlfn.ACOTH
 		"=_xlfn.ACOTH()": "ACOTH requires 1 numeric arguments",
 		// _xlfn.ARABIC
-		"_xlfn.ARABIC()": "ARABIC requires 1 numeric arguments",
+		"=_xlfn.ARABIC()": "ARABIC requires 1 numeric arguments",
 		// ASIN
 		"=ASIN()": "ASIN requires 1 numeric arguments",
 		// ASINH
@@ -166,6 +204,27 @@ func TestCalcCellValue(t *testing.T) {
 		// _xlfn.CEILING.MATH
 		"=_xlfn.CEILING.MATH()":        "CEILING.MATH requires at least 1 argument",
 		"=_xlfn.CEILING.MATH(1,2,3,4)": "CEILING.MATH allows at most 3 arguments",
+		// _xlfn.CEILING.PRECISE
+		"=_xlfn.CEILING.PRECISE()":      "CEILING.PRECISE requires at least 1 argument",
+		"=_xlfn.CEILING.PRECISE(1,2,3)": "CEILING.PRECISE allows at most 2 arguments",
+		// COMBIN
+		"=COMBIN()":     "COMBIN requires 2 argument",
+		"=COMBIN(-1,1)": "COMBIN requires number >= number_chosen",
+		// _xlfn.COMBINA
+		"=_xlfn.COMBINA()":      "COMBINA requires 2 argument",
+		"=_xlfn.COMBINA(-1,1)":  "COMBINA requires number > number_chosen",
+		"=_xlfn.COMBINA(-1,-1)": "COMBIN requires number >= number_chosen",
+		// COS
+		"=COS()": "COS requires 1 numeric arguments",
+		// COSH
+		"=COSH()": "COSH requires 1 numeric arguments",
+		// _xlfn.COT
+		"=COT()": "COT requires 1 numeric arguments",
+		// _xlfn.COTH
+		"=COTH()": "COTH requires 1 numeric arguments",
+		// _xlfn.CSC
+		"_xlfn.CSC()":  "CSC requires 1 numeric arguments",
+		"_xlfn.CSC(0)": "#NAME?",
 		// GCD
 		"=GCD()":     "GCD requires at least 1 argument",
 		"=GCD(-1)":   "GCD only accepts positive arguments",