diff --git a/bigNumber.go b/bigNumber.go index 4026303..8919366 100644 --- a/bigNumber.go +++ b/bigNumber.go @@ -384,62 +384,68 @@ func (a *BigNumber) Sub(b *BigNumber) *BigNumber { // Multiply multiplies two BigNumber instances and returns a new BigNumber instance. func (a *BigNumber) Multiply(b *BigNumber) *BigNumber { - num1, num2 := a.value, b.value - if strings.Contains(num1, a.format.decimalSeparator) || strings.Contains(num2, a.format.decimalSeparator) { - num1, num2 = normalizeDecimal(num1, num2, a.format.decimalSeparator) - } - - intPart1, decPart1 := splitDecimal(num1, a.format.decimalSeparator) - intPart2, decPart2 := splitDecimal(num2, a.format.decimalSeparator) - - intPart1 += decPart1 - intPart2 += decPart2 - - m := len(decPart1) + len(decPart2) - len1 := len(intPart1) - len2 := len(intPart2) - - result := make([]int, len1+len2) - for i := len1 - 1; i >= 0; i-- { - for j := len2 - 1; j >= 0; j-- { - mul := a.toInteger(string(intPart1[i])) * a.toInteger(string(intPart2[j])) - p1 := i + j - p2 := i + j + 1 - sum := mul + result[p2] - result[p1] += sum / a.format.base - result[p2] = sum % a.format.base - } - } + num1, num2 := a.value, b.value + if strings.Contains(num1, a.format.decimalSeparator) || strings.Contains(num2, a.format.decimalSeparator) { + num1, num2 = normalizeDecimal(num1, num2, a.format.decimalSeparator) + } - resultStr := "" - for _, digit := range result { - resultStr += a.toNumber(digit) - } + intPart1, decPart1 := splitDecimal(num1, a.format.decimalSeparator) + intPart2, decPart2 := splitDecimal(num2, a.format.decimalSeparator) - if m > 0 { - resultStr = insertDecimalPoint(resultStr, m, a.format.decimalSeparator) - } - resultStr = strings.TrimLeft(resultStr, "0") - resultStr = insertDecimalPoint(resultStr, a.format.maxDecimal, a.format.decimalSeparator) + intPart1 += decPart1 + intPart2 += decPart2 + + m := len(decPart1) + len(decPart2) + len1 := len(intPart1) + len2 := len(intPart2) + + result := make([]int, len1+len2) + for i := len1 - 1; i >= 0; i-- { + for j := len2 - 1; j >= 0; j-- { + mul := a.toInteger(string(intPart1[i])) * a.toInteger(string(intPart2[j])) + p1 := i + j + p2 := i + j + 1 + sum := mul + result[p2] + result[p1] += sum / a.format.base + result[p2] = sum % a.format.base + } + } + resultStr := "" + for _, digit := range result { + resultStr += a.toNumber(digit) + } - integerPart,decimalPart := splitDecimal(resultStr,a.format.decimalSeparator) + if m > 0 { + resultStr = insertDecimalPoint(resultStr, m, a.format.decimalSeparator) + } - resultStr = strings.Join([]string{integerPart,PadEndString(decimalPart,a.format.maxDecimal,"0")},a.format.decimalSeparator) + // 修正前导零和小数点处理逻辑 + resultStr = strings.TrimLeft(resultStr, "0") + if strings.HasPrefix(resultStr, a.format.decimalSeparator) { + resultStr = "0" + resultStr + } + if strings.Contains(resultStr, a.format.decimalSeparator) { + parts := strings.Split(resultStr, a.format.decimalSeparator) + if len(parts[1]) < a.format.maxDecimal { + parts[1] = PadEndString(parts[1], a.format.maxDecimal, "0") + } + resultStr = strings.Join(parts, a.format.decimalSeparator) + } - if(a.format.maxDecimal <= 0){ + if a.format.maxDecimal <= 0 { resultStr = strings.TrimRight(resultStr, "0") } if strings.HasSuffix(resultStr, a.format.decimalSeparator) { resultStr = strings.TrimSuffix(resultStr, a.format.decimalSeparator) } - if resultStr == "" { - resultStr = "0" - } + if resultStr == "" { + resultStr = "0" + } - resultBigNumber := NewBigNumber(resultStr) - resultBigNumber.sign = a.sign * b.sign - return resultBigNumber + resultBigNumber := NewBigNumber(resultStr) + resultBigNumber.sign = a.sign * b.sign + return resultBigNumber } // Divide divides two BigNumber instances and returns the quotient and remainder. diff --git a/slice.go b/slice.go index e87dbb8..b572991 100644 --- a/slice.go +++ b/slice.go @@ -1,96 +1,119 @@ package utils - func Chunk[T any](slice []T, size int) [][]T { - var chunks [][]T - for i := 0; i < len(slice); i += size { - end := i + size - if end > len(slice) { - end = len(slice) - } - chunks = append(chunks, slice[i:end]) - } - return chunks + var chunks [][]T + for i := 0; i < len(slice); i += size { + end := i + size + if end > len(slice) { + end = len(slice) + } + chunks = append(chunks, slice[i:end]) + } + return chunks } +func Reverse[T any](slice []T) []T { + buf := make([]T, len(slice)) + begin := 0 + end := len(slice) - 1 + for begin < end { + buf[begin] = slice[end] + buf[end] = slice[begin] + begin++ + end-- + } + return buf +} -func Reduce[T any](slice []T, reducer func(T, T) T, initialValue T) T { - result := initialValue - - for _, val := range slice { - result = reducer(result, val) - } +func Reduce[T any](slice []T, reducer func(T, T, int) T, accumulator T) T { + result := accumulator + for key, val := range slice { + result = reducer(result, val, key) + } - return result + return result } func Map[T any](slice []T, mapper func(T) T) []T { - result := make([]T, len(slice)) + result := make([]T, len(slice)) - for i, val := range slice { - result[i] = mapper(val) - } + for i, val := range slice { + result[i] = mapper(val) + } - return result + return result } func Filter[T any](slice []T, predicate func(T) bool) []T { - var result []T + var result []T - for _, val := range slice { - if predicate(val) { - result = append(result, val) - } - } + for _, val := range slice { + if predicate(val) { + result = append(result, val) + } + } - return result + return result } func PadEnd[T any](slice []T, targetLength int, padValue T) []T { - currentLength := len(slice) - paddingLength := targetLength - currentLength - if paddingLength <= 0 || currentLength > targetLength { - return slice - } - newSlice := make([]T, 0,paddingLength) - for i := 0; i < paddingLength; i++ { - newSlice = append(newSlice, padValue) - } - newSlice = append(slice, newSlice...) - - return newSlice + currentLength := len(slice) + paddingLength := targetLength - currentLength + if paddingLength <= 0 || currentLength > targetLength { + return slice + } + newSlice := make([]T, 0, paddingLength) + for i := 0; i < paddingLength; i++ { + newSlice = append(newSlice, padValue) + } + newSlice = append(slice, newSlice...) + + return newSlice +} + +func PadEndString(val string, length int, padValue string) string { + currentLength := len(val) + paddingLength := length - currentLength + if paddingLength <= 0 || currentLength > length { + return val + } + pad := "" + for i := 0; i < paddingLength; i++ { + pad = pad + padValue + } + return val + pad } func PadStart[T any](slice []T, targetLength int, padValue T) []T { - currentLength := len(slice) - paddingLength := targetLength - currentLength - if paddingLength <= 0 || currentLength > targetLength { - return slice - } + currentLength := len(slice) + paddingLength := targetLength - currentLength + if paddingLength <= 0 || currentLength > targetLength { + return slice + } - newSlice := make([]T, 0, paddingLength) - for i := 0; i < paddingLength; i++ { - newSlice = append(newSlice, padValue) - } + newSlice := make([]T, 0, paddingLength) + for i := 0; i < paddingLength; i++ { + newSlice = append(newSlice, padValue) + } - newSlice = append(newSlice, slice...) + newSlice = append(newSlice, slice...) - return newSlice + return newSlice } func GroupBy[T any, K comparable](slice []T, getKey func(T) K) map[K][]T { - groups := make(map[K][]T) + groups := make(map[K][]T) - for _, item := range slice { - key := getKey(item) - groups[key] = append(groups[key], item) - } + for _, item := range slice { + key := getKey(item) + groups[key] = append(groups[key], item) + } - return groups + return groups } -func ForEach[T any](slice []T,callback func(value T,key int)){ - for k, v := range slice { - callback(v,k) - } +func ForEach[T any](slice []T, callback func(value T, key int)) { + for k, v := range slice { + callback(v, k) + } } diff --git a/utils_test.go b/utils_test.go index 075137a..4e7b035 100644 --- a/utils_test.go +++ b/utils_test.go @@ -161,7 +161,7 @@ func TestTimes(t *testing.T) { } func TestReduce(t *testing.T) { - sum := utils.Reduce([]int{1, 2, 3, 5, 6}, func(accumulator, currentValue int) int { + sum := utils.Reduce([]int{1, 2, 3, 5, 6}, func(accumulator, currentValue int,index int) int { return accumulator + currentValue }, 0) if sum != 17 { @@ -352,7 +352,12 @@ func TestNumberConver(t *testing.T) { } func TestOmit(t *testing.T) { + type Addr struct { + Position string + Last bool + } type People struct { + Addr Name string Age int Address string @@ -551,3 +556,77 @@ func TestNewResult(t *testing.T) { t.Errorf("Expected value 'success', but got %v", result.Value()) } } + +func TestBigNumber(t *testing.T){ + num1 := utils.NewBigNumber("12") + num2 := utils.NewBigNumber("12") + + sum := num1.Plus(num2) + if sum.String() != "24" { + t.Error(fmt.Sprintf("%s + %s Expected %s",num1.String(), num2.String(), sum.String())) + } + + diff := num1.Minus(num2) + fmt.Printf("%s - %s = %s\n", num1.String(), num2.String(), diff.String()) + + num3 := utils.NewBigNumber("89.0000001") + num4 := utils.NewBigNumber("0.001") + sum5 := num3.Plus(num4) + if sum5.String() != "89.0010001" { + t.Error(fmt.Sprintf("%s + %s Expected %s",num3.String(), num4.String(), sum5.String())) + } + + num6 := utils.NewBigNumber("0.02") + num7 := utils.NewBigNumber("0.01") + sum6 := num6.Plus(num7) + if sum6.String() != "0.03" { + t.Error(fmt.Sprintf(" %s + %s expected %s,but got %s",num6.String(),num7.String(),"0.03",sum6.String())) + } + + if num6.Multiply(num7).String() != "0.000200" { + t.Error(fmt.Sprintf(" %s * %s expected %s,but got %s",num6.String(),num7.String(),"0.0002",num6.Multiply(num7).String())) + } + + num8 := utils.NewBigNumber("8") + num9 := utils.NewBigNumber("9") + sum7 := num8.Minus(num9) + if sum7.String() != "-1" { + t.Error(fmt.Sprintf(" %s - %s expected %s,but got %s",num8.String(),num9.String(),"-1",sum7.String())) + } + num10 := utils.NewBigNumber("1") + num11 := utils.NewBigNumber("-1") + if !num10.IsGreaterThan(num11) { + t.Error("1 should be great than -1") + } + + num12 := utils.NewBigNumber("-1") + num13 := utils.NewBigNumber("-1") + if num12.Plus(num13).String() != "-2" { + t.Error("-1 + -1 should be -2") + } + + if num12.Minus(num13).String() != "0" { + t.Error("-1 - -1 should be 0") + } + + num14 := utils.NewBigNumber("1") + num15 := utils.NewBigNumber("2") + result := num14.Divide(num15) + if result.String() != "0.500000" { + t.Error(fmt.Sprintf(" 1 / 2 should be 0.5, but got %s",result.String())) + } + nums16 := utils.NewBigNumber("-12") + if nums16.AbsoluteValue().String() != "12" { + t.Error(fmt.Sprintf("the -12 absolute value should be 12, but got %s",nums16.AbsoluteValue().String())) + } + + num17 := utils.NewBigNumber("12") + s := num17.Sum("12","33","68","92","76","82","64") + fmt.Print(s.String()) +} + + +func TestRevese(t *testing.T){ + d := utils.Reverse([]string{"A","B","C","D","E","F"}) + fmt.Printf("%v",d) +}