github.com/mithrandie/csvq@v1.18.1/lib/query/arithmetic.go (about) 1 package query 2 3 import ( 4 "errors" 5 "math" 6 7 "github.com/mithrandie/csvq/lib/value" 8 ) 9 10 var errIntegerDevidedByZero = errors.New("integer devided by zero") 11 12 func Calculate(p1 value.Primary, p2 value.Primary, operator int) (value.Primary, error) { 13 if i1 := value.ToIntegerStrictly(p1); !value.IsNull(i1) { 14 if i2 := value.ToIntegerStrictly(p2); !value.IsNull(i2) { 15 val1 := i1.(*value.Integer).Raw() 16 val2 := i2.(*value.Integer).Raw() 17 18 value.Discard(i1) 19 value.Discard(i2) 20 return calculateInteger(val1, val2, operator) 21 } 22 value.Discard(i1) 23 } 24 25 if f1 := value.ToFloat(p1); !value.IsNull(f1) { 26 if f2 := value.ToFloat(p2); !value.IsNull(f2) { 27 val1 := f1.(*value.Float).Raw() 28 val2 := f2.(*value.Float).Raw() 29 30 value.Discard(f1) 31 value.Discard(f2) 32 return calculateFloat(val1, val2, operator), nil 33 } 34 value.Discard(f1) 35 } 36 37 return value.NewNull(), nil 38 } 39 40 func calculateInteger(i1 int64, i2 int64, operator int) (value.Primary, error) { 41 var result int64 = 0 42 switch operator { 43 case '+': 44 result = i1 + i2 45 case '-': 46 result = i1 - i2 47 case '*': 48 result = i1 * i2 49 case '/': 50 if i2 == 0 { 51 return nil, errIntegerDevidedByZero 52 } 53 result = i1 / i2 54 case '%': 55 if i2 == 0 { 56 return nil, errIntegerDevidedByZero 57 } 58 result = i1 % i2 59 } 60 61 return value.NewInteger(result), nil 62 } 63 64 func calculateFloat(f1 float64, f2 float64, operator int) value.Primary { 65 result := 0.0 66 switch operator { 67 case '+': 68 result = f1 + f2 69 case '-': 70 result = f1 - f2 71 case '*': 72 result = f1 * f2 73 case '/': 74 result = f1 / f2 75 case '%': 76 result = math.Remainder(f1, f2) 77 } 78 79 return value.NewFloat(result) 80 }