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  }