numeric.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package sprig
  2. import (
  3. "fmt"
  4. "math"
  5. "strconv"
  6. "strings"
  7. "github.com/shopspring/decimal"
  8. "github.com/spf13/cast"
  9. )
  10. func toFloat64(v interface{}) float64 {
  11. return cast.ToFloat64(v)
  12. }
  13. func toInt(v interface{}) int {
  14. return cast.ToInt(v)
  15. }
  16. func toInt64(v interface{}) int64 {
  17. return cast.ToInt64(v)
  18. }
  19. func max(a interface{}, i ...interface{}) int64 {
  20. aa := toInt64(a)
  21. for _, b := range i {
  22. bb := toInt64(b)
  23. if bb > aa {
  24. aa = bb
  25. }
  26. }
  27. return aa
  28. }
  29. func maxf(a interface{}, i ...interface{}) float64 {
  30. aa := toFloat64(a)
  31. for _, b := range i {
  32. bb := toFloat64(b)
  33. aa = math.Max(aa, bb)
  34. }
  35. return aa
  36. }
  37. func min(a interface{}, i ...interface{}) int64 {
  38. aa := toInt64(a)
  39. for _, b := range i {
  40. bb := toInt64(b)
  41. if bb < aa {
  42. aa = bb
  43. }
  44. }
  45. return aa
  46. }
  47. func minf(a interface{}, i ...interface{}) float64 {
  48. aa := toFloat64(a)
  49. for _, b := range i {
  50. bb := toFloat64(b)
  51. aa = math.Min(aa, bb)
  52. }
  53. return aa
  54. }
  55. func until(count int) []int {
  56. step := 1
  57. if count < 0 {
  58. step = -1
  59. }
  60. return untilStep(0, count, step)
  61. }
  62. func untilStep(start, stop, step int) []int {
  63. v := []int{}
  64. if stop < start {
  65. if step >= 0 {
  66. return v
  67. }
  68. for i := start; i > stop; i += step {
  69. v = append(v, i)
  70. }
  71. return v
  72. }
  73. if step <= 0 {
  74. return v
  75. }
  76. for i := start; i < stop; i += step {
  77. v = append(v, i)
  78. }
  79. return v
  80. }
  81. func floor(a interface{}) float64 {
  82. aa := toFloat64(a)
  83. return math.Floor(aa)
  84. }
  85. func ceil(a interface{}) float64 {
  86. aa := toFloat64(a)
  87. return math.Ceil(aa)
  88. }
  89. func round(a interface{}, p int, rOpt ...float64) float64 {
  90. roundOn := .5
  91. if len(rOpt) > 0 {
  92. roundOn = rOpt[0]
  93. }
  94. val := toFloat64(a)
  95. places := toFloat64(p)
  96. var round float64
  97. pow := math.Pow(10, places)
  98. digit := pow * val
  99. _, div := math.Modf(digit)
  100. if div >= roundOn {
  101. round = math.Ceil(digit)
  102. } else {
  103. round = math.Floor(digit)
  104. }
  105. return round / pow
  106. }
  107. func toDecimal(v interface{}) int64 {
  108. result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
  109. if err != nil {
  110. return 0
  111. }
  112. return result
  113. }
  114. func seq(params ...int) string {
  115. increment := 1
  116. switch len(params) {
  117. case 0:
  118. return ""
  119. case 1:
  120. start := 1
  121. end := params[0]
  122. if end < start {
  123. increment = -1
  124. }
  125. return intArrayToString(untilStep(start, end+increment, increment), " ")
  126. case 3:
  127. start := params[0]
  128. end := params[2]
  129. step := params[1]
  130. if end < start {
  131. increment = -1
  132. if step > 0 {
  133. return ""
  134. }
  135. }
  136. return intArrayToString(untilStep(start, end+increment, step), " ")
  137. case 2:
  138. start := params[0]
  139. end := params[1]
  140. step := 1
  141. if end < start {
  142. step = -1
  143. }
  144. return intArrayToString(untilStep(start, end+step, step), " ")
  145. default:
  146. return ""
  147. }
  148. }
  149. func intArrayToString(slice []int, delimeter string) string {
  150. return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]")
  151. }
  152. func execDecimalOp(a interface{}, b []interface{}, f func(d1, d2 decimal.Decimal) decimal.Decimal) float64 {
  153. prt := decimal.NewFromFloat(toFloat64(a))
  154. for _, x := range b {
  155. dx := decimal.NewFromFloat(toFloat64(x))
  156. prt = f(prt, dx)
  157. }
  158. rslt, _ := prt.Float64()
  159. return rslt
  160. }