diff --git a/decimal.go b/decimal.go index 682189d..1afbe39 100644 --- a/decimal.go +++ b/decimal.go @@ -244,6 +244,34 @@ func (d *Decimal) FromString(value string) bool { return true } +func (d *Decimal) RescaleOverflow(mantissa uint8) (value *Decimal, overflow bool) { + if d == nil { + return nil, false + } + + if mantissa == d.mantissa { + return d, false + } + + if mantissa > d.mantissa { + _, isOverflow := d.value.MulOverflow(d.value, ExpScale(int16(mantissa-d.mantissa))) + if isOverflow { + return nil, isOverflow + } + + d.mantissa = mantissa + return d, false + } + + if mantissa < d.mantissa { + d.value.Div(d.value, ExpScale(int16(d.mantissa-mantissa))) + d.mantissa = mantissa + return d, false + } + + return d, false +} + func (d *Decimal) Rescale(mantissa uint8) *Decimal { if d == nil { return nil diff --git a/wei.go b/wei.go index 4b0c347..19c1e08 100644 --- a/wei.go +++ b/wei.go @@ -11,3 +11,16 @@ func ConvertToWei(dec *Decimal, mantissa uint8) *big.Int { return NewDecimal(dec).Rescale(mantissa).ToBig() } + +func ConvertToWeiOverflow(dec *Decimal, mantissa uint8) (wei *big.Int, overflow bool) { + if dec == nil || dec.value == nil { + return new(big.Int).SetUint64(0), false + } + + value, isOverflow := NewDecimal(dec).RescaleOverflow(mantissa) + if isOverflow { + return nil, isOverflow + } + + return value.ToBig(), false +} diff --git a/wei_test.go b/wei_test.go index c608693..2dd277f 100644 --- a/wei_test.go +++ b/wei_test.go @@ -56,4 +56,24 @@ func TestConvertToWei(t *testing.T) { expected, ok = new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) assert.True(t, ok) assert.Equal(t, expected, ConvertToWei(actual, 18)) + + actual, ok = NewDecimalFromString("115792089237316195423570985008687907853269984665640564039457584007913129639935") + assert.True(t, ok) + expected, ok = new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) + assert.True(t, ok) + actualWei, overflow := ConvertToWeiOverflow(actual, 18) + assert.True(t, overflow) + assert.Nil(t, actualWei) + + actual, ok = NewDecimalFromString("115792089237316195423570985008687907853269984665640564039457.584007913129639936") + assert.False(t, ok) + assert.Nil(t, actual) + + actual, ok = NewDecimalFromString("115792089237316195423570985008687907853269984665640564039457.584007913129639935") + assert.True(t, ok) + expected, ok = new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) + assert.True(t, ok) + actualWei, overflow = ConvertToWeiOverflow(actual, 18) + assert.False(t, overflow) + assert.Equal(t, expected, actualWei) }