ArithmeticOperator.go

package main

import (
	"fmt"
	"math/big"
	"strconv"
)

// add 함수는 문자열 배열로 표현된 숫자들을 더한 결과를 반환합니다.
func add(vars []string) *big.Float {
	result := big.NewFloat(0)

	for _, varStr := range vars {
		varVal, _, err := big.ParseFloat(varStr, 10, 0, big.ToZero)
		if err != nil {
			varVal = big.NewFloat(0)
		}
		result.Add(result, varVal)
	}

	return result
}

// sub 함수는 문자열 배열로 표현된 숫자들을 빼기 연산한 결과를 반환합니다.
func sub(vars []string) *big.Float {
	if len(vars) == 0 {
		return big.NewFloat(0)
	}

	result, _, err := big.ParseFloat(vars[0], 10, 0, big.ToZero)
	if err != nil {
		result = big.NewFloat(0)
	}

	for i := 1; i < len(vars); i++ {
		varVal, _, err := big.ParseFloat(vars[i], 10, 0, big.ToZero)
		if err != nil {
			varVal = big.NewFloat(0)
		}
		result.Sub(result, varVal)
	}

	return result
}

// mul 함수는 문자열 배열로 표현된 숫자들을 곱한 결과를 반환합니다.
func mul(vars []string) *big.Float {
	if len(vars) == 0 {
		return big.NewFloat(0)
	}

	result, _, err := big.ParseFloat(vars[0], 10, 0, big.ToZero)
	if err != nil {
		result = big.NewFloat(0)
	}

	for i := 1; i < len(vars); i++ {
		varVal, _, err := big.ParseFloat(vars[i], 10, 0, big.ToZero)
		if err != nil {
			varVal = big.NewFloat(0)
		}
		result.Mul(result, varVal)
	}

	return result
}

// div 함수는 문자열 배열로 표현된 숫자들을 나눈 결과를 반환합니다.
func div(vars []string) *big.Float {
	if len(vars) == 0 {
		return big.NewFloat(0)
	}

	result, _, err := big.ParseFloat(vars[0], 10, 0, big.ToZero)
	if err != nil {
		result = big.NewFloat(0)
	}

	for i := 1; i < len(vars); i++ {
		varVal, _, err := big.ParseFloat(vars[i], 10, 0, big.ToZero)
		if err != nil {
			varVal = big.NewFloat(0)
		}
		result.Quo(result, varVal)
	}

	return result
}

// preciseAdd 함수는 지정된 소수점 자리수를 사용하여 숫자들을 더한 결과를 반환합니다.
func preciseAdd(vars []string, scale int) *big.Float {
	if scale < 0 || scale > 10 {
		scale = 0
	}

	left, _, err1 := big.ParseFloat(vars[0], 10, 0, big.ToZero)
	right, _, err2 := big.ParseFloat(vars[1], 10, 0, big.ToZero)

	if err1 != nil || err2 != nil {
		return big.NewFloat(0)
	}

	result := new(big.Float).Add(left, right)
	result.SetPrec(uint(scale))

	return result
}

// preciseSub 함수는 지정된 소수점 자리수를 사용하여 숫자들을 뺀 결과를 반환합니다.
func preciseSub(vars []string, scale int) *big.Float {
	if scale < 0 || scale > 10 {
		scale = 0
	}

	left, _, err1 := big.ParseFloat(vars[0], 10, 0, big.ToZero)
	right, _, err2 := big.ParseFloat(vars[1], 10, 0, big.ToZero)

	if err1 != nil || err2 != nil {
		return big.NewFloat(0)
	}

	result := new(big.Float).Sub(left, right)
	result.SetPrec(uint(scale))

	return result
}

// preciseMul 함수는 지정된 소수점 자리수를 사용하여 숫자들을 곱한 결과를 반환합니다.
func preciseMul(vars []string, scale int) *big.Float {
	if scale < 0 || scale > 10 {
		scale = 0
	}

	left, _, err1 := big.ParseFloat(vars[0], 10, 0, big.ToZero)
	right, _, err2 := big.ParseFloat(vars[1], 10, 0, big.ToZero)

	if err1 != nil || err2 != nil {
		return big.NewFloat(0)
	}

	result := new(big.Float).Mul(left, right)
	result.SetPrec(uint(scale))

	return result
}

// preciseDiv 함수는 지정된 소수점 자리수를 사용하여 숫자들을 나눈 결과를 반환합니다.
func preciseDiv(vars []string, scale int) *big.Float {
	if scale < 0 || scale > 10 {
		scale = 0
	}

	left, _, err1 := big.ParseFloat(vars[0], 10, 0, big.ToZero)
	right, _, err2 := big.ParseFloat(vars[1], 10, 0, big.ToZero)

	if err1 != nil || err2 != nil {
		return big.NewFloat(0)
	}

	result := new(big.Float).Quo(left, right)
	result.SetPrec(uint(scale))

	return result
}

// scale 함수는 주어진 값의 소수점 자리수를 반환합니다.
func scale(value string) int {
	varVal, _, err := big.ParseFloat(value, 10, 0, big.ToZero)
	if err != nil {
		return 0
	}
	_, scale := varVal.Float64()
	return scale
}

func main() {
	// 예제 사용
	nums := []string{"10.5", "5.5", "2"}
	fmt.Println("Add:", add(nums))
	fmt.Println("Sub:", sub(nums))
	fmt.Println("Mul:", mul(nums))
	fmt.Println("Div:", div(nums))

	// Precise operations
	fmt.Println("Precise Add:", preciseAdd([]string{"10.5", "5.5"}, 2))
	fmt.Println("Precise Sub:", preciseSub([]string{"10.5", "5.5"}, 2))
	fmt.Println("Precise Mul:", preciseMul([]string{"10.5", "5.5"}, 2))
	fmt.Println("Precise Div:", preciseDiv([]string{"10.5", "5.5"}, 2))
}

설명

  • add(vars []string) *big.Float: 문자열 배열로 표현된 숫자들을 더한 결과를 반환합니다.

  • sub(vars []string) *big.Float: 문자열 배열로 표현된 숫자들을 빼기 연산한 결과를 반환합니다.

  • mul(vars []string) *big.Float: 문자열 배열로 표현된 숫자들을 곱한 결과를 반환합니다.

  • div(vars []string) *big.Float: 문자열 배열로 표현된 숫자들을 나눈 결과를 반환합니다.

  • preciseAdd(vars []string, scale int) *big.Float: 지정된 소수점 자리수를 사용하여 숫자들을 더한 결과를 반환합니다.

  • preciseSub(vars []string, scale int) *big.Float: 지정된 소수점 자리수를 사용하여 숫자들을 뺀 결과를 반환합니다.

  • preciseMul(vars []string, scale int) *big.Float: 지정된 소수점 자리수를 사용하여 숫자들을 곱한 결과를 반환합니다.

  • preciseDiv(vars []string, scale int) *big.Float: 지정된 소수점 자리수를 사용하여 숫자들을 나눈 결과를 반환합니다.

  • scale(value string) int: 주어진 값의 소수점 자리수를 반환합니다.

  • main(): 각 함수의 사용 예제를 출력합니다.

함수 설명

  1. add 함수

    • vars 배열에 있는 모든 숫자를 더한 결과를 반환합니다.

  2. sub 함수

    • vars 배열의 첫 번째 숫자에서 나머지 숫자들을 차례대로 뺀 결과를 반환합니다.

  3. mul 함수

    • vars 배열에 있는 모든 숫자를 곱한 결과를 반환합니다.

  4. div 함수

    • vars 배열의 첫 번째 숫자를 나머지 숫자들로 차례대로 나눈 결과를 반환합니다.

  5. preciseAdd 함수

    • 두 숫자를 더하고, 지정된 scale 정밀도로 결과를 반환합니다.

  6. preciseSub 함수

    • 두 숫자를 빼고, 지정된 scale 정밀도로 결과를 반환합니다.

  7. preciseMul 함수

    • 두 숫자를 곱하고, 지정된 scale 정밀도로 결과를 반환합니다.

  8. preciseDiv 함수

    • 두 숫자를 나누고, 지정된 scale 정밀도로 결과를 반환합니다.

  9. scale 함수

    • 주어진 숫자의 소수점 자릿수를 반환합니다.

코드 개선 사항

  1. precise 함수 개선

    • preciseAdd, preciseSub, preciseMul, preciseDiv 함수에서 scale이 0인 경우가 많아서 정밀도가 원하는 만큼 조정되지 않을 수 있습니다.

    • 이 문제를 해결하려면 big.FloatSetPrec 메서드 대신 SetPrecSetMode 메서드를 적절히 사용하여 원하는 정밀도로 설정해야 합니다.

Last updated