func-math.go: mul() and add() now support fractions
This commit is contained in:
parent
7c748f0e31
commit
5809de419f
87
func-math.go
87
func-math.go
@ -10,16 +10,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func checkNumberParamExpected(funcName string, paramValue any, paramPos int) (err error) {
|
func checkNumberParamExpected(funcName string, paramValue any, paramPos int) (err error) {
|
||||||
if !(isNumber(paramValue) || isList(paramValue) || isIterator(paramValue)) {
|
if !(isNumber(paramValue) || isList(paramValue) || isFraction(paramValue)) {
|
||||||
err = fmt.Errorf("%s(): param nr %d has wrong type %T, number expected", funcName, paramPos+1, paramValue)
|
err = fmt.Errorf("%s(): param nr %d has wrong type %T, number expected", funcName, paramPos+1, paramValue)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func doAdd(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
func doAdd(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
||||||
var sumAsFloat = false
|
var sumAsFloat, sumAsFract bool
|
||||||
var floatSum float64 = 0.0
|
var floatSum float64 = 0.0
|
||||||
var intSum int64 = 0
|
var intSum int64 = 0
|
||||||
|
var fractSum *fraction
|
||||||
var v any
|
var v any
|
||||||
|
|
||||||
for v, err = it.Next(); err == nil; v, err = it.Next() {
|
for v, err = it.Next(); err == nil; v, err = it.Next() {
|
||||||
@ -36,19 +37,37 @@ func doAdd(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
|||||||
if err = checkNumberParamExpected(name, v, it.Index()); err != nil {
|
if err = checkNumberParamExpected(name, v, it.Index()); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if array, ok := v.([]any); ok {
|
if array, ok := v.(*ListType); ok {
|
||||||
if v, err = doAdd(ctx, name, NewFlatArrayIterator(array)); err != nil {
|
if v, err = doAdd(ctx, name, NewFlatArrayIterator(*array)); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sumAsFloat && isFloat(v) {
|
if !sumAsFloat {
|
||||||
sumAsFloat = true
|
if isFloat(v) {
|
||||||
floatSum = float64(intSum)
|
sumAsFloat = true
|
||||||
|
if sumAsFract {
|
||||||
|
floatSum = fractSum.toFloat()
|
||||||
|
} else {
|
||||||
|
floatSum = float64(intSum)
|
||||||
|
}
|
||||||
|
} else if !sumAsFract && isFraction(v) {
|
||||||
|
fractSum = newFraction(intSum, 1)
|
||||||
|
sumAsFract = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sumAsFloat {
|
if sumAsFloat {
|
||||||
floatSum += numAsFloat(v)
|
floatSum += numAsFloat(v)
|
||||||
|
} else if sumAsFract {
|
||||||
|
var item *fraction
|
||||||
|
var ok bool
|
||||||
|
if item, ok = v.(*fraction); !ok {
|
||||||
|
iv, _ := v.(int64)
|
||||||
|
item = newFraction(iv, 1)
|
||||||
|
}
|
||||||
|
fractSum = sumFract(fractSum, item)
|
||||||
} else {
|
} else {
|
||||||
iv, _ := v.(int64)
|
iv, _ := v.(int64)
|
||||||
intSum += iv
|
intSum += iv
|
||||||
@ -58,6 +77,8 @@ func doAdd(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
|||||||
err = nil
|
err = nil
|
||||||
if sumAsFloat {
|
if sumAsFloat {
|
||||||
result = floatSum
|
result = floatSum
|
||||||
|
} else if sumAsFract {
|
||||||
|
result = fractSum
|
||||||
} else {
|
} else {
|
||||||
result = intSum
|
result = intSum
|
||||||
}
|
}
|
||||||
@ -71,28 +92,58 @@ func addFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doMul(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
func doMul(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
||||||
var mulAsFloat = false
|
var mulAsFloat, mulAsFract bool
|
||||||
var floatProd float64 = 1.0
|
var floatProd float64 = 1.0
|
||||||
var intProd int64 = 1
|
var intProd int64 = 1
|
||||||
|
var fractProd *fraction
|
||||||
var v any
|
var v any
|
||||||
|
|
||||||
for v, err = it.Next(); err == nil; v, err = it.Next() {
|
for v, err = it.Next(); err == nil; v, err = it.Next() {
|
||||||
if err = checkNumberParamExpected(name, v, it.Index()); err != nil {
|
if subIter, ok := v.(Iterator); ok {
|
||||||
break
|
if v, err = doAdd(ctx, name, subIter); err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
if array, ok := v.([]any); ok {
|
|
||||||
if v, err = doMul(ctx, name, NewFlatArrayIterator(array)); err != nil {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if subIter.HasOperation(cleanName) {
|
||||||
|
if _, err = subIter.CallOperation(cleanName, nil); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err = checkNumberParamExpected(name, v, it.Index()); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if array, ok := v.(*ListType); ok {
|
||||||
|
if v, err = doMul(ctx, name, NewFlatArrayIterator(*array)); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mulAsFloat && isFloat(v) {
|
if !mulAsFloat {
|
||||||
mulAsFloat = true
|
if isFloat(v) {
|
||||||
floatProd = float64(intProd)
|
mulAsFloat = true
|
||||||
|
if mulAsFract {
|
||||||
|
floatProd = fractProd.toFloat()
|
||||||
|
} else {
|
||||||
|
floatProd = float64(intProd)
|
||||||
|
}
|
||||||
|
} else if !mulAsFract && isFraction(v) {
|
||||||
|
fractProd = newFraction(intProd, 1)
|
||||||
|
mulAsFract = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if mulAsFloat {
|
if mulAsFloat {
|
||||||
floatProd *= numAsFloat(v)
|
floatProd *= numAsFloat(v)
|
||||||
|
} else if mulAsFract {
|
||||||
|
var item *fraction
|
||||||
|
var ok bool
|
||||||
|
if item, ok = v.(*fraction); !ok {
|
||||||
|
iv, _ := v.(int64)
|
||||||
|
item = newFraction(iv, 1)
|
||||||
|
}
|
||||||
|
fractProd = mulFract(fractProd, item)
|
||||||
} else {
|
} else {
|
||||||
iv, _ := v.(int64)
|
iv, _ := v.(int64)
|
||||||
intProd *= iv
|
intProd *= iv
|
||||||
@ -102,6 +153,8 @@ func doMul(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
|||||||
err = nil
|
err = nil
|
||||||
if mulAsFloat {
|
if mulAsFloat {
|
||||||
result = floatProd
|
result = floatProd
|
||||||
|
} else if mulAsFract {
|
||||||
|
result = fractProd
|
||||||
} else {
|
} else {
|
||||||
result = intProd
|
result = intProd
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user