github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/ceil/ceil.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ceil
    16  
    17  import (
    18  	"math"
    19  	"strconv"
    20  	"strings"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  
    24  	"github.com/matrixorigin/matrixone/pkg/vectorize/floor"
    25  )
    26  
    27  /*ceil(1.23) -----> 2.0
    28  ceil(1.23, 0) ----> 2.0
    29  ceil(1.23, 1) -----> 1.3
    30  ceil(12.34, -1) ---- > 20.0*/
    31  
    32  var (
    33  	CeilUint8      func([]uint8, []uint8, int64) []uint8
    34  	CeilUint16     func([]uint16, []uint16, int64) []uint16
    35  	CeilUint32     func([]uint32, []uint32, int64) []uint32
    36  	CeilUint64     func([]uint64, []uint64, int64) []uint64
    37  	CeilInt8       func([]int8, []int8, int64) []int8
    38  	CeilInt16      func([]int16, []int16, int64) []int16
    39  	CeilInt32      func([]int32, []int32, int64) []int32
    40  	CeilInt64      func([]int64, []int64, int64) []int64
    41  	CeilFloat32    func([]float32, []float32, int64) []float32
    42  	CeilFloat64    func([]float64, []float64, int64) []float64
    43  	CeilDecimal128 func(int32, []types.Decimal128, []types.Decimal128, int64) []types.Decimal128
    44  )
    45  
    46  func init() {
    47  	CeilUint8 = ceilUint8
    48  	CeilUint16 = ceilUint16
    49  	CeilUint32 = ceilUint32
    50  	CeilUint64 = ceilUint64
    51  	CeilInt8 = ceilInt8
    52  	CeilInt16 = ceilInt16
    53  	CeilInt32 = ceilInt32
    54  	CeilInt64 = ceilInt64
    55  	CeilFloat32 = ceilFloat32
    56  	CeilFloat64 = ceilFloat64
    57  	CeilDecimal128 = ceilDecimal128
    58  }
    59  
    60  func ceilUint8(xs, rs []uint8, digits int64) []uint8 {
    61  	// maximum uint8 number is 255, so we only need to worry about a few digit cases,
    62  	switch {
    63  	case digits >= 0:
    64  		return xs
    65  	case digits == -1 || digits == -2:
    66  		scale := uint8(floor.ScaleTable[-digits])
    67  		for i := range xs {
    68  			t := xs[i] % scale
    69  			s := xs[i]
    70  			if t != 0 {
    71  				s -= t
    72  				rs[i] = (s + scale) / scale * scale
    73  			} else {
    74  				rs[i] = xs[i]
    75  			}
    76  		}
    77  	case digits <= -floor.MaxUint8digits:
    78  		for i := range xs {
    79  			rs[i] = 0
    80  		}
    81  	}
    82  	return rs
    83  }
    84  
    85  func ceilUint16(xs, rs []uint16, digits int64) []uint16 {
    86  	switch {
    87  	case digits >= 0:
    88  		return xs
    89  	case digits > -floor.MaxUint16digits:
    90  		scale := uint16(floor.ScaleTable[-digits])
    91  		for i := range xs {
    92  			t := xs[i] % scale
    93  			s := xs[i]
    94  			if t != 0 {
    95  				s -= t
    96  				rs[i] = (s + scale) / scale * scale
    97  			} else {
    98  				rs[i] = xs[i]
    99  			}
   100  		}
   101  	case digits <= -floor.MaxUint16digits:
   102  		for i := range xs {
   103  			rs[i] = 0
   104  		}
   105  	}
   106  	return rs
   107  }
   108  
   109  func ceilUint32(xs, rs []uint32, digits int64) []uint32 {
   110  	switch {
   111  	case digits >= 0:
   112  		return xs
   113  	case digits > -floor.MaxUint32digits:
   114  		scale := uint32(floor.ScaleTable[-digits])
   115  		for i := range xs {
   116  			t := xs[i] % scale
   117  			s := xs[i]
   118  			if t != 0 {
   119  				s -= t
   120  				rs[i] = (s + scale) / scale * scale
   121  			} else {
   122  				rs[i] = xs[i]
   123  			}
   124  		}
   125  	case digits <= -floor.MaxUint32digits:
   126  		for i := range xs {
   127  			rs[i] = 0
   128  		}
   129  	}
   130  	return rs
   131  }
   132  
   133  func ceilUint64(xs, rs []uint64, digits int64) []uint64 {
   134  	switch {
   135  	case digits >= 0:
   136  		return xs
   137  	case digits > -floor.MaxUint64digits:
   138  		scale := floor.ScaleTable[-digits]
   139  		for i := range xs {
   140  			t := xs[i] % scale
   141  			s := xs[i]
   142  			if t != 0 {
   143  				s -= t
   144  				rs[i] = (s + scale) / scale * scale
   145  			} else {
   146  				rs[i] = xs[i]
   147  			}
   148  		}
   149  	case digits <= -floor.MaxUint64digits:
   150  		for i := range xs {
   151  			rs[i] = 0
   152  		}
   153  	}
   154  	return rs
   155  }
   156  
   157  func ceilInt8(xs, rs []int8, digits int64) []int8 {
   158  	switch {
   159  	case digits >= 0:
   160  		return xs
   161  	case digits == -1 || digits == -2:
   162  		scale := int8(floor.ScaleTable[-digits])
   163  		for i := range xs {
   164  			t := xs[i] % scale
   165  			s := xs[i]
   166  			if t != 0 {
   167  				s -= t
   168  				if s >= 0 && xs[i] > 0 {
   169  					rs[i] = (s + scale) / scale * scale
   170  				} else {
   171  					rs[i] = s
   172  				}
   173  			} else {
   174  				rs[i] = xs[i]
   175  			}
   176  		}
   177  	case digits <= -floor.MaxInt8digits:
   178  		for i := range xs {
   179  			rs[i] = 0
   180  		}
   181  	}
   182  	return rs
   183  }
   184  
   185  func ceilInt16(xs, rs []int16, digits int64) []int16 {
   186  	switch {
   187  	case digits >= 0:
   188  		return xs
   189  	case digits > -floor.MaxInt16digits:
   190  		scale := int16(floor.ScaleTable[-digits])
   191  		for i := range xs {
   192  			t := xs[i] % scale
   193  			s := xs[i]
   194  			if t != 0 {
   195  				s -= t
   196  				if s >= 0 && xs[i] > 0 {
   197  					rs[i] = (s + scale) / scale * scale
   198  				} else {
   199  					rs[i] = s
   200  				}
   201  			} else {
   202  				rs[i] = xs[i]
   203  			}
   204  		}
   205  	case digits <= -floor.MaxInt16digits:
   206  		for i := range xs {
   207  			rs[i] = 0
   208  		}
   209  	}
   210  	return rs
   211  }
   212  
   213  func ceilInt32(xs, rs []int32, digits int64) []int32 {
   214  	switch {
   215  	case digits >= 0:
   216  		return xs
   217  	case digits > -floor.MaxInt32digits:
   218  		scale := int32(floor.ScaleTable[-digits])
   219  		for i := range xs {
   220  			t := xs[i] % scale
   221  			s := xs[i]
   222  			if t != 0 {
   223  				s -= t
   224  				if s >= 0 && xs[i] > 0 {
   225  					rs[i] = (s + scale) / scale * scale
   226  				} else {
   227  					rs[i] = s
   228  				}
   229  			} else {
   230  				rs[i] = xs[i]
   231  			}
   232  		}
   233  	case digits <= -floor.MaxInt32digits:
   234  		for i := range xs {
   235  			rs[i] = 0
   236  		}
   237  	}
   238  	return rs
   239  }
   240  
   241  func ceilInt64(xs, rs []int64, digits int64) []int64 {
   242  	switch {
   243  	case digits >= 0:
   244  		return xs
   245  	case digits > -floor.MaxInt64digits:
   246  		scale := int64(floor.ScaleTable[-digits])
   247  		for i := range xs {
   248  			t := xs[i] % scale
   249  			s := xs[i]
   250  			if t != 0 {
   251  				s -= t
   252  				if s >= 0 && xs[i] > 0 {
   253  					rs[i] = (s + scale) / scale * scale
   254  				} else {
   255  					rs[i] = s
   256  				}
   257  			} else {
   258  				rs[i] = xs[i]
   259  			}
   260  		}
   261  	case digits <= -floor.MaxInt64digits:
   262  		for i := range xs {
   263  			rs[i] = 0
   264  		}
   265  	}
   266  	return rs
   267  }
   268  
   269  func ceilFloat32(xs, rs []float32, digits int64) []float32 {
   270  	if digits == 0 {
   271  		for i := range xs {
   272  			rs[i] = float32(math.Ceil(float64(xs[i])))
   273  		}
   274  	} else {
   275  		scale := float32(math.Pow10(int(digits)))
   276  		for i := range xs {
   277  			value := xs[i] * scale
   278  			rs[i] = float32(math.Ceil(float64(value))) / scale
   279  		}
   280  	}
   281  	return rs
   282  }
   283  
   284  func ceilFloat64(xs, rs []float64, digits int64) []float64 {
   285  	if digits == 0 {
   286  		for i := range xs {
   287  			rs[i] = math.Ceil(xs[i])
   288  		}
   289  	} else {
   290  		scale := math.Pow10(int(digits))
   291  		for i := range xs {
   292  			value := xs[i] * scale
   293  			rs[i] = math.Ceil(value) / scale
   294  		}
   295  	}
   296  	return rs
   297  }
   298  
   299  func ceilDecimal128(scale int32, xs, rs []types.Decimal128, _ int64) []types.Decimal128 {
   300  	for i := range xs {
   301  		strs := strings.Split(xs[i].ToStringWithScale(scale), ".")
   302  		x, _ := types.Decimal128_FromString(strs[0])
   303  		if strs[0][0] == '-' || len(strs) == 1 {
   304  			rs[i] = x
   305  			continue
   306  		}
   307  
   308  		v, _ := strconv.ParseFloat(strs[1], 64)
   309  		if v > float64(0) {
   310  			x = x.AddInt64(1)
   311  		}
   312  		rs[i] = x
   313  	}
   314  	return rs
   315  }