decimal icon indicating copy to clipboard operation
decimal copied to clipboard

MaxScale not working

Open eduardhasanaj opened this issue 6 years ago • 5 comments

I am trying to have fixed scale after multiply operations I trient to set MaxScale before mult but the scale becomes twice. What is the correct way to handle this?

eduardhasanaj avatar Nov 24 '19 21:11 eduardhasanaj

@ericlagergren please any help on that is appreciated. I need to have only two digits after decimal point like 5.00.

eduardhasanaj avatar Nov 25 '19 15:11 eduardhasanaj

Could you provide an example of what you're trying right now?

ericlagergren avatar Nov 28 '19 01:11 ericlagergren

Here is the code

tax := decimal.WithContext(decimal.Context{
		MaxScale: 2,
		RoundingMode: decimal.ToNearestAway,
	})

When I perform multiplication I see more than two digits after decimal point. I am using Braintree and for prices it does not make sense tpo have more than two digits after decimal point.

eduardhasanaj avatar Nov 29 '19 16:11 eduardhasanaj

It is a little bit unclear how MaxScale works at the moment. Consider this example: https://play.golang.org/p/Sv-m8pU3N60

package main

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

func main() {

	ctx := decimal.Context{
		MaxScale: 2,
		RoundingMode: decimal.ToNearestAway,	
	}
	
	x := decimal.WithContext(ctx).SetUint64(1).SetScale(999)

	fmt.Printf("x=%v\n", x) // prints 1E-999
	fmt.Printf("scale=%d\n", x.Scale()) // prints 999
	fmt.Printf("maxscale=%d\n", x.Context.MaxScale) // prints 2
		
	// How can x's scale be 999, if x's max scale is 2?
}

(Should x should contain Inf at this point?)

I'm not sure if this is by design or a bug, but it seems MaxScale and MinScale are only honored by certain operations like Big.Reduce and Big.Round.

rdingwall avatar Jan 18 '21 16:01 rdingwall

Similar code: https://play.golang.org/p/V4jIH6WX4W4

package main

import (
	"fmt"

	"github.com/ericlagergren/decimal"
)

func main() {

	var decimalContext = decimal.Context{
		MaxScale:     4,
		Precision:    10,
	}

	a, _ := decimal.WithContext(decimalContext).SetString("100000")
	b, _ := decimal.WithContext(decimalContext).SetString("0.123456789")
	c := decimal.WithContext(decimalContext).Add(a, b)

	fmt.Println("MaxScale: 4, Precision: 10")
	fmt.Printf("a = %v\n", a)
	fmt.Printf("b = %v\n", b)
	fmt.Printf("c = %v\n", c)

	decimalContext = decimal.Context{
		MaxScale:     5,
		Precision:    10,
	}

	a, _ = decimal.WithContext(decimalContext).SetString("100000")
	b, _ = decimal.WithContext(decimalContext).SetString("0.123456789")
	c = decimal.WithContext(decimalContext).Add(a, b)

	fmt.Println("MaxScale: 5, Precision: 10")
	fmt.Printf("a = %v\n", a)
	fmt.Printf("b = %v\n", b)
	fmt.Printf("c = %v\n", c)

	decimalContext = decimal.Context{
		MaxScale:     4,
		Precision:    20,
	}

	a, _ = decimal.WithContext(decimalContext).SetString("100000")
	b, _ = decimal.WithContext(decimalContext).SetString("0.123456789")
	c = decimal.WithContext(decimalContext).Add(a, b)

	fmt.Println("MaxScale: 4, Precision: 20")
	fmt.Printf("a = %v\n", a)
	fmt.Printf("b = %v\n", b)
	fmt.Printf("c = %v\n", c)
}

MaxScale: 4, Precision: 10 a = 100000 b = 0.123456789 c = -0E-999999999999999999 MaxScale: 5, Precision: 10 a = 100000 b = 0.123456789 c = 100000.1235 MaxScale: 4, Precision: 20 a = 100000 b = 0.123456789 c = Infinity

cvigo avatar Jul 19 '21 10:07 cvigo