mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 19:23:40 +00:00
Multiply by a scalar
Signed-off-by: Yuki Iwai <yuki.iwai.tz@gmail.com>
This commit is contained in:
parent
4381eb7237
commit
79325b6178
@ -203,43 +203,37 @@ func (a *int64Amount) Sub(b int64Amount) bool {
|
||||
return a.Add(int64Amount{value: -b.value, scale: b.scale})
|
||||
}
|
||||
|
||||
// Mul multiplies two int64Amounts together, matching scales.
|
||||
// It will return false and not mutate a if overflow or underflow would result.
|
||||
// Mul adds the value of a to itself n times.
|
||||
// It will return false and not mutate a if overflow or underflow would result.
|
||||
func (a *int64Amount) Mul(b int64Amount) bool {
|
||||
// Mul multiplies the provided b to the current amount, or
|
||||
// returns false if overflow or underflow would result.
|
||||
func (a *int64Amount) Mul(b int64) bool {
|
||||
switch {
|
||||
case b.value == 0:
|
||||
a.value = 0
|
||||
return true
|
||||
case a.value == 0:
|
||||
a.value = 0
|
||||
a.scale = b.scale
|
||||
return true
|
||||
case a.scale == b.scale:
|
||||
c, ok := int64Multiply(a.value, b.value)
|
||||
case b == 0:
|
||||
a.value = 0
|
||||
a.scale = 0
|
||||
return true
|
||||
case a.scale == 0:
|
||||
c, ok := int64Multiply(a.value, b)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
a.value = c
|
||||
case a.scale > b.scale:
|
||||
c, ok := positiveScaleInt64(a.value, a.scale-b.scale)
|
||||
case a.scale > 0:
|
||||
c, ok := int64Multiply(a.value, b)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c, ok = int64Multiply(c, b.value)
|
||||
if !ok {
|
||||
if _, ok = positiveScaleInt64(c, a.scale); !ok {
|
||||
return false
|
||||
}
|
||||
a.scale = b.scale
|
||||
a.value = c
|
||||
default:
|
||||
c, ok := positiveScaleInt64(b.value, b.scale-a.scale)
|
||||
c, ok := int64Multiply(a.value, b)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c, ok = int64Multiply(a.value, c)
|
||||
if !ok {
|
||||
if _, ok = negativeScaleInt64(c, -a.scale); !ok {
|
||||
return false
|
||||
}
|
||||
a.value = c
|
||||
|
@ -91,18 +91,21 @@ func TestInt64AmountAdd(t *testing.T) {
|
||||
|
||||
func TestInt64AmountMul(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
a, b, c int64Amount
|
||||
ok bool
|
||||
a int64Amount
|
||||
b int64
|
||||
c int64Amount
|
||||
ok bool
|
||||
}{
|
||||
{int64Amount{value: 100, scale: 1}, int64Amount{value: 10, scale: 2}, int64Amount{value: 10000, scale: 1}, true},
|
||||
{int64Amount{value: 100, scale: 1}, int64Amount{value: 1, scale: 2}, int64Amount{value: 1000, scale: 1}, true},
|
||||
{int64Amount{value: 100, scale: 1}, int64Amount{value: 1, scale: 100}, int64Amount{value: 1, scale: 100}, false},
|
||||
{int64Amount{value: -5, scale: 2}, int64Amount{value: 50, scale: 1}, int64Amount{value: -2500, scale: 1}, true},
|
||||
{int64Amount{value: -5, scale: 2}, int64Amount{value: 5, scale: 2}, int64Amount{value: -25, scale: 2}, true},
|
||||
{int64Amount{value: 100, scale: 1}, 1000, int64Amount{value: 100000, scale: 1}, true},
|
||||
{int64Amount{value: 100, scale: -1}, 1000, int64Amount{value: 100000, scale: -1}, true},
|
||||
{int64Amount{value: 1, scale: 100}, 10, int64Amount{value: 1, scale: 100}, false},
|
||||
{int64Amount{value: 1, scale: -100}, 10, int64Amount{value: 1, scale: -100}, false},
|
||||
{int64Amount{value: -5, scale: 2}, 500, int64Amount{value: -2500, scale: 2}, true},
|
||||
{int64Amount{value: -5, scale: -2}, 500, int64Amount{value: -2500, scale: -2}, true},
|
||||
|
||||
{int64Amount{value: mostPositive, scale: -1}, int64Amount{value: 1, scale: -1}, int64Amount{value: 9223372036854775807, scale: -1}, true},
|
||||
{int64Amount{value: mostPositive, scale: -1}, int64Amount{value: 0, scale: -1}, int64Amount{value: 0, scale: -1}, true},
|
||||
{int64Amount{value: mostPositive / 10, scale: 1}, int64Amount{value: 10, scale: 0}, int64Amount{value: mostPositive, scale: -1}, false},
|
||||
{int64Amount{value: mostPositive, scale: -1}, 10, int64Amount{value: mostPositive, scale: -1}, false},
|
||||
{int64Amount{value: mostPositive, scale: -1}, 0, int64Amount{value: 0, scale: 0}, true},
|
||||
{int64Amount{value: mostPositive / 10, scale: 1}, 10, int64Amount{value: mostPositive / 10, scale: 1}, false},
|
||||
} {
|
||||
c := test.a
|
||||
ok := c.Mul(test.b)
|
||||
@ -118,21 +121,6 @@ func TestInt64AmountMul(t *testing.T) {
|
||||
t.Errorf("%v: overflow multiplication mutated source: %d", test, c)
|
||||
}
|
||||
}
|
||||
|
||||
// multiplication is commutative
|
||||
c = test.b
|
||||
if ok = c.Mul(test.a); ok != test.ok {
|
||||
t.Errorf("%v: unexpected ok: %t", test, ok)
|
||||
}
|
||||
if ok {
|
||||
if c != test.c {
|
||||
t.Errorf("%v: unexpected result: %d", test, c)
|
||||
}
|
||||
} else {
|
||||
if c != test.b {
|
||||
t.Errorf("%v: overflow multiplication mutated source: %d", test, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -592,17 +592,14 @@ func (q *Quantity) Sub(y Quantity) {
|
||||
q.ToDec().d.Dec.Sub(q.d.Dec, y.AsDec())
|
||||
}
|
||||
|
||||
// Mul multiplies the provided y quantity to the current value. If the current value is zero,
|
||||
// the format of the quantity will be updated to the format of y.
|
||||
func (q *Quantity) Mul(y Quantity) {
|
||||
// Mul multiplies the provided y to the current value.
|
||||
// It will return false if the result is inexact. Otherwise, it will return true.
|
||||
func (q *Quantity) Mul(y int64) bool {
|
||||
q.s = ""
|
||||
if q.IsZero() {
|
||||
q.Format = y.Format
|
||||
if q.d.Dec == nil && q.i.Mul(y) {
|
||||
return true
|
||||
}
|
||||
if q.d.Dec == nil && y.d.Dec == nil && q.i.Mul(y.i) {
|
||||
return
|
||||
}
|
||||
q.ToDec().d.Dec.Mul(q.d.Dec, y.AsDec())
|
||||
return q.ToDec().d.Dec.Mul(q.d.Dec, inf.NewDec(y, inf.Scale(0))).UnscaledBig().IsInt64()
|
||||
}
|
||||
|
||||
// Cmp returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
|
||||
|
@ -1140,21 +1140,26 @@ func TestAdd(t *testing.T) {
|
||||
func TestMul(t *testing.T) {
|
||||
tests := []struct {
|
||||
a Quantity
|
||||
b Quantity
|
||||
b int64
|
||||
expected Quantity
|
||||
ok bool
|
||||
}{
|
||||
{decQuantity(10, 0, DecimalSI), decQuantity(1, 1, DecimalSI), decQuantity(100, 0, DecimalSI)},
|
||||
{decQuantity(10, 0, DecimalSI), decQuantity(1, 0, BinarySI), decQuantity(10, 0, DecimalSI)},
|
||||
{decQuantity(10, 0, BinarySI), decQuantity(1, 0, DecimalSI), decQuantity(10, 0, BinarySI)},
|
||||
{Quantity{Format: DecimalSI}, decQuantity(50, 0, DecimalSI), decQuantity(0, 0, DecimalSI)},
|
||||
{decQuantity(50, 0, DecimalSI), Quantity{Format: DecimalSI}, decQuantity(0, 0, DecimalSI)},
|
||||
{Quantity{Format: DecimalSI}, Quantity{Format: DecimalSI}, decQuantity(0, 0, DecimalSI)},
|
||||
{decQuantity(10, 0, DecimalSI), 10, decQuantity(100, 0, DecimalSI), true},
|
||||
{decQuantity(10, 0, DecimalSI), 1, decQuantity(10, 0, DecimalSI), true},
|
||||
{decQuantity(10, 0, BinarySI), 1, decQuantity(10, 0, BinarySI), true},
|
||||
{Quantity{Format: DecimalSI}, 50, decQuantity(0, 0, DecimalSI), true},
|
||||
{decQuantity(50, 0, DecimalSI), 0, decQuantity(0, 0, DecimalSI), true},
|
||||
{Quantity{Format: DecimalSI}, 0, decQuantity(0, 0, DecimalSI), true},
|
||||
|
||||
{decQuantity(mostPositive, 0, DecimalSI), 10, decQuantity(mostPositive, 1, DecimalSI), false},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
test.a.Mul(test.b)
|
||||
if ok := test.a.Mul(test.b); test.ok != ok {
|
||||
t.Errorf("[%d] Expected ok: %t, got ok: %t", i, test.ok, ok)
|
||||
}
|
||||
if test.a.Cmp(test.expected) != 0 {
|
||||
t.Errorf("[%d] Expected %q, got %q", i, test.expected.String(), test.a.String())
|
||||
t.Errorf("[%d] Expected %q, got %q", i, test.expected.AsDec().String(), test.a.AsDec().String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user