Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split a value x ways #155

Open
M-Lewinski opened this issue Sep 24, 2020 · 0 comments
Open

Split a value x ways #155

M-Lewinski opened this issue Sep 24, 2020 · 0 comments

Comments

@M-Lewinski
Copy link

M-Lewinski commented Sep 24, 2020

tl;dr How to split value x ways correctly?

Disclaimer: personally I always try to first look for information and details about specific subjects before asking. I hope that this issue may help other people like me who try to move from shopspring/decimal to a library with better performance.

Problem, I’m currently facing is splitting number X ways. For example if we have value 100 that has to be split between 3 entities:
I will have to give two of them 33.33333 and one of them will receive the remainder which is 33.33334. After adding all the values together I will get the base value which is 100.

I understand that representing fractions of value would sometimes require an infinite amount of memory but it’s possible to do this with specified precision which for library shopspring/decimal is 16.

Here is the example code of splitting value x ways:

package main

import (
	"fmt"
	"github.com/shopspring/decimal"
)

func split(value, number int) (decimal.Decimal, decimal.Decimal){
	baseValue := decimal.NewFromInt(int64(value))
	num := decimal.NewFromInt(int64(number))
	lower := baseValue.Div(num)
	higher := lower.Mul(num)
	higher = baseValue.Sub(higher).Add(lower)
	return higher, lower
}

func check(higher, lower decimal.Decimal, number int) decimal.Decimal{
	baseValue := decimal.Zero
	for i := 1 ; i < number ; i++ {
		baseValue = baseValue.Add(lower)
	}
	baseValue = baseValue.Add(higher)
	return baseValue
}
func main(){
	baseValue := 100
	number := 13
	higher, lower := split(baseValue,number)
	baseValue2 := check(higher,lower,number)
	if baseValue2.Equal(decimal.NewFromInt(int64(baseValue))){
		fmt.Println("Correct")
	} else {
		fmt.Println("Incorrect")
	}
}

So far above code always return correct values for most of my test cases.

Creating similar code with this library will return correct results for values like 100 split 3 ways. But for example 100 split 13 ways will return a value of 99.9999… .
Is it possible to achieve the same results using this decimal library?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant