diff --git a/constraints.go b/constraints.go new file mode 100644 index 0000000..682fbc0 --- /dev/null +++ b/constraints.go @@ -0,0 +1,33 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gmath + +// Signed is a constraint that permits any signed integer type. +// If future releases of Go add new predeclared signed integer types, +// this constraint will be modified to include them. +type Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +// Unsigned is a constraint that permits any unsigned integer type. +// If future releases of Go add new predeclared unsigned integer types, +// this constraint will be modified to include them. +type Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +// Integer is a constraint that permits any integer type. +// If future releases of Go add new predeclared integer types, +// this constraint will be modified to include them. +type Integer interface { + Signed | Unsigned +} + +// Float is a constraint that permits any floating-point type. +// If future releases of Go add new predeclared floating-point types, +// this constraint will be modified to include them. +type Float interface { + ~float32 | ~float64 +} diff --git a/gmath.go b/gmath.go index 7efe240..9b02630 100644 --- a/gmath.go +++ b/gmath.go @@ -4,32 +4,27 @@ package gmath import "math" -// Ints is a constraint that is satisfied by any integer number type. -type Ints interface { - ~int | ~int8 | ~int16 | ~int32 | ~int64 -} - -// Uints is a constraint that is satisfied by any unsigned integer number type. -type Uints interface { - ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr -} - -// Floats is a constraint that is satisfied by any floating point number type. -type Floats interface { - ~float32 | ~float64 -} +const ( + // Binary equivalent for a float32 "signaling" NaN. + uvsnan32 = 0xFFC00000 + // Binary equivalent for float32 positive infinity. + uvinf32 = 0x7F800000 + // Binary equivalent for float32 negative infinity. + uvneginf32 = 0xFF800000 +) // Abs returns the absolute value of x. // // Special cases are: +// // Abs(±Inf) = +Inf // Abs(NaN) = NaN -// Abs(int(math.MinInt)) = math.MinInt -// Abs(int8(math.MinInt8)) = math.MinInt8 -// Abs(int16(math.MinInt16)) = math.MinInt16 -// Abs(int32(math.MinInt32)) = math.MinInt32 -// Abs(int64(math.MinInt64)) = math.MinInt64 -func Abs[T Ints | Floats](x T) T { +// Abs(int(math.MinInt)) = math.MinInt +// Abs(int8(math.MinInt8)) = math.MinInt8 +// Abs(int16(math.MinInt16)) = math.MinInt16 +// Abs(int32(math.MinInt32)) = math.MinInt32 +// Abs(int64(math.MinInt64)) = math.MinInt64 +func Abs[T Signed | Float](x T) T { if IsNaN(x) || x >= 0 { return x } @@ -39,14 +34,15 @@ func Abs[T Ints | Floats](x T) T { // Copysign returns a value with the magnitude of x and the sign of y. // // Special cases are: -// Copysign(NaN, y) = NaN -// Copysign(x, NaN) = Abs(x) -// Copysign(int(math.MinInt), y >= 0) = math.MinInt -// Copysign(int8(math.MinInt8), y >= 0) = math.MinInt8 -// Copysign(int16(math.MinInt16), y >= 0) = math.MinInt16 -// Copysign(int32(math.MinInt32), y >= 0) = math.MinInt32 -// Copysign(int64(math.MinInt64), y >= 0) = math.MinInt64 -func Copysign[T0, T1 Ints | Floats](x T0, y T1) T0 { +// +// Copysign(NaN, y) = NaN +// Copysign(x, NaN) = Abs(x) +// Copysign(int(math.MinInt), y >= 0) = math.MinInt +// Copysign(int8(math.MinInt8), y >= 0) = math.MinInt8 +// Copysign(int16(math.MinInt16), y >= 0) = math.MinInt16 +// Copysign(int32(math.MinInt32), y >= 0) = math.MinInt32 +// Copysign(int64(math.MinInt64), y >= 0) = math.MinInt64 +func Copysign[T0, T1 Signed | Float](x T0, y T1) T0 { if IsNaN(x) { return x } @@ -62,15 +58,16 @@ func Copysign[T0, T1 Ints | Floats](x T0, y T1) T0 { return -x } +// From https://cs.opensource.google/go/go/+/go1.17.3:src/math/dim.go;l=13 + // Dim returns the maximum of x-y or 0. // // Special cases are: +// // Dim(+Inf, +Inf) = NaN // Dim(-Inf, -Inf) = NaN // Dim(x, NaN) = Dim(NaN, x) = NaN -// -// From https://cs.opensource.google/go/go/+/go1.17.3:src/math/dim.go;l=13 -func Dim[T Ints | Uints | Floats](x, y T) T { +func Dim[T Integer | Float](x, y T) T { // The special cases result in NaN after the subtraction: // +Inf - +Inf = NaN // -Inf - -Inf = NaN @@ -82,26 +79,21 @@ func Dim[T Ints | Uints | Floats](x, y T) T { return 0 } // v is positive or NaN - return T(v) -} - -// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0. -func Inf[T Floats](sign int) T { - return T(math.Inf(sign)) + return v } // IsInf reports whether f is an infinity, according to sign. // If sign > 0, IsInf reports whether f is positive infinity. // If sign < 0, IsInf reports whether f is negative infinity. // If sign == 0, IsInf reports whether f is either infinity. -func IsInf[T Ints | Uints | Floats](x T, sign int) bool { +func IsInf[T Integer | Float](x T, sign int) bool { return math.IsInf(float64(x), sign) } -// IsNaN reports whether f is an IEEE 754 ``not-a-number'' value. -// // From https://cs.opensource.google/go/go/+/go1.17.3:src/math/bits.go;l=34 -func IsNaN[T Ints | Uints | Floats](x T) bool { + +// IsNaN reports whether f is an IEEE 754 “not-a-number” value. +func IsNaN[T Integer | Float](x T) bool { // IEEE 754 says that only NaNs satisfy x != x. // No integer values satisfy x != x. return x != x @@ -110,23 +102,26 @@ func IsNaN[T Ints | Uints | Floats](x T) bool { // Log returns the natural logarithm of x. // // Special cases are: +// // Log(+Inf) = +Inf // Log(0) = -Inf // Log(x < 0) = NaN // Log(NaN) = NaN // -// Note that for integer values greater than 9007199254740993, some precision -// may be lost because the input is converted to a float64. -func Log[T Ints | Uints | Floats](x T) float64 { +// Note that for integer values greater than 9007199254740993 or less than +// -9007199254740993, some precision may be lost because the input is converted +// to a float64. +func Log[T Integer | Float](x T) float64 { return math.Log(float64(x)) } // Log10 returns the decimal logarithm of x. // The special cases are the same as for Log. // -// Note that for integer values greater than 9007199254740993, some precision -// may be lost because the input is converted to a float64. -func Log10[T Ints | Uints | Floats](x T) float64 { +// Note that for integer values greater than 9007199254740993 or less than +// -9007199254740993, some precision may be lost because the input is converted +// to a float64. +func Log10[T Integer | Float](x T) float64 { return math.Log10(float64(x)) } @@ -134,82 +129,150 @@ func Log10[T Ints | Uints | Floats](x T) float64 { // It is more accurate than Log(1 + x) when x is near zero. // // Special cases are: +// // Log1p(+Inf) = +Inf // Log1p(±0) = ±0 // Log1p(-1) = -Inf // Log1p(x < -1) = NaN // Log1p(NaN) = NaN // -// Note that for integer values greater than 9007199254740993, some precision -// may be lost because the input is converted to a float64. -func Log1p[T Ints | Uints | Floats](x T) float64 { +// Note that for integer values greater than 9007199254740993 or less than +// -9007199254740993, some precision may be lost because the input is converted +// to a float64. +func Log1p[T Integer | Float](x T) float64 { return math.Log1p(float64(x)) } // Log2 returns the binary logarithm of x. // The special cases are the same as for Log. // -// Note that for integer values greater than 9007199254740993, some precision -// may be lost because the input is converted to a float64. -func Log2[T Ints | Uints | Floats](x T) float64 { +// Note that for integer values greater than 9007199254740993 or less than +// -9007199254740993, some precision may be lost because the input is converted +// to a float64. +func Log2[T Integer | Float](x T) float64 { return math.Log2(float64(x)) } +// Based on https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/math/logb.go;l=14 + // Logb returns the binary exponent of x. // // Special cases are: +// // Logb(±Inf) = +Inf // Logb(0) = -Inf // Logb(NaN) = NaN +func Logb[T Float](x T) T { + // special cases + switch { + case x == 0: + return T(math.Inf(-1)) + case IsInf(x, 0): + return T(math.Inf(1)) + case IsNaN(x): + // If the input is a NaN, return the original input without converting + // it to type T. Float conversion zeros the NaN signal bit, converting + // it from a "signaling NaN" to a "quiet NaN". To preserve the value of + // the input NaN, always return it without any conversion. + return x + } + return T(Ilogb(x)) +} + +// Ilogb returns the binary exponent of x as an integer. // -// Note that for integer values greater than 9007199254740993, some precision -// may be lost because the input is converted to a float64. -func Logb[T Ints | Uints | Floats](x T) float64 { - return math.Logb(float64(x)) +// Special cases are: +// +// Ilogb(±Inf) = MaxInt32 +// Ilogb(0) = MinInt32 +// Ilogb(NaN) = MaxInt32 +func Ilogb[T Float](x T) int { + // This conversion from float32 to float64 should be safe. When converting + // from float32 to float64, the value and precision of the exponent part of + // an IEEE 754 floating point number do not change and the range of exponent + // values representable by a float64 is a superset of the range of exponent + // values representable by a float32. + return math.Ilogb(float64(x)) } +// Based on https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/math/dim.go;l=44-61 + // Max returns the larger of x or y. // // Special cases are: +// // Max(x, +Inf) = Max(+Inf, x) = +Inf // Max(x, NaN) = Max(NaN, x) = NaN // Max(+0, ±0) = Max(±0, +0) = +0 // Max(-0, -0) = -0 -func Max[T Ints | Uints | Floats](x, y T) T { - if IsNaN(x) { +func Max[T Integer | Float](x, y T) T { + // special cases + switch { + case IsInf(x, 1): return x - } - if IsNaN(y) { + case IsInf(y, 1): + return y + case IsNaN(x): + return x + case IsNaN(y): return y + case x == 0 && x == y: + if math.Signbit(float64(x)) { + return y + } + return x } - if x > y { return x } return y } +// Based on https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/math/dim.go;l=77-94 + // Min returns the smaller of x or y. // // Special cases are: +// // Min(x, -Inf) = Min(-Inf, x) = -Inf // Min(x, NaN) = Min(NaN, x) = NaN // Min(-0, ±0) = Min(±0, -0) = -0 -func Min[T Ints | Uints | Floats](x, y T) T { - if IsNaN(x) { +func Min[T Integer | Float](x, y T) T { + // special cases + switch { + case IsInf(x, -1): return x - } - if IsNaN(y) { + case IsInf(y, -1): + return y + case IsNaN(x): + return x + case IsNaN(y): + return y + case x == 0 && x == y: + if math.Signbit(float64(x)) { + return x + } return y } - if x < y { return x } return y } -// NaN returns an IEEE 754 ``not-a-number'' value. -func NaN[T Floats]() T { - return T(math.NaN()) +// Inf32 returns a float32 positive infinity if sign >= 0, negative infinity if +// sign < 0. +func Inf32(sign int) float32 { + var v uint32 + if sign >= 0 { + v = uvinf32 + } else { + v = uvneginf32 + } + return math.Float32frombits(v) +} + +// NaN32 returns a float32 IEEE 754 “not-a-number” value. +func NaN32() float32 { + return math.Float32frombits(uvsnan32) } diff --git a/gmath_test.go b/gmath_test.go index daeab66..28af1bd 100644 --- a/gmath_test.go +++ b/gmath_test.go @@ -4,10 +4,25 @@ import ( "fmt" "math" "testing" +) - "github.com/stretchr/testify/assert" +const ( + // Binary equivalent for float32 negative zero. + uvnegzero32 = 0x80000000 + // Binary equivalent for float64 negative zero. + uvnegzero64 = 0x8000000000000000 ) +// negzero32 returns a float32 negative zero. +func negzero32() float32 { + return math.Float32frombits(uvnegzero32) +} + +// negzero64 returns a float64 negataive zero. +func negzero64() float64 { + return math.Float64frombits(uvnegzero64) +} + type myInt int func TestAbs(t *testing.T) { @@ -24,7 +39,7 @@ func TestAbs(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Abs(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -49,7 +64,7 @@ func TestAbs(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Abs(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -74,7 +89,7 @@ func TestAbs(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Abs(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -96,59 +111,53 @@ func TestAbs(t *testing.T) { want: math.MaxFloat32, }, { - input: Inf[float32](1), - want: Inf[float32](1), + input: Inf32(1), + want: Inf32(1), }, { - input: Inf[float32](-1), - want: Inf[float32](1), + input: Inf32(-1), + want: Inf32(1), }, { - input: NaN[float32](), - want: NaN[float32](), + input: NaN32(), + want: NaN32(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Abs(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input float64 - want float64 }{ { input: 1, - want: 1, }, { input: -1, - want: 1, }, { input: math.Inf(1), - want: math.Inf(1), }, { input: math.Inf(1), - want: math.Inf(1), }, { input: math.Inf(-1), - want: math.Inf(1), }, { input: math.NaN(), - want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Abs(test.input) got := Abs(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) @@ -168,7 +177,7 @@ func TestCopysign(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Copysign(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -201,7 +210,7 @@ func TestCopysign(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Copysign(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -234,7 +243,7 @@ func TestCopysign(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Copysign(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -268,79 +277,69 @@ func TestCopysign(t *testing.T) { want: math.MaxFloat32, }, { - input: [2]float32{Inf[float32](1), -5}, - want: Inf[float32](-1), + input: [2]float32{Inf32(1), -5}, + want: Inf32(-1), }, { - input: [2]float32{Inf[float32](-1), 5}, - want: Inf[float32](1), + input: [2]float32{Inf32(-1), 5}, + want: Inf32(1), }, { - input: [2]float32{NaN[float32](), 5}, - want: NaN[float32](), + input: [2]float32{NaN32(), 5}, + want: NaN32(), }, { - input: [2]float32{-3, NaN[float32]()}, + input: [2]float32{-3, NaN32()}, want: 3, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Copysign(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input [2]float64 - want float64 }{ { input: [2]float64{3.2, 5}, - want: 3.2, }, { input: [2]float64{-3.2, -5}, - want: -3.2, }, { input: [2]float64{3.2, -5}, - want: -3.2, }, { input: [2]float64{-3.2, 5}, - want: 3.2, }, { input: [2]float64{math.MaxFloat64, -5}, - want: -math.MaxFloat64, }, { input: [2]float64{-math.MaxFloat64, 5}, - want: math.MaxFloat64, }, { input: [2]float64{math.Inf(1), -5}, - want: math.Inf(-1), }, { input: [2]float64{math.Inf(-1), 5}, - want: math.Inf(1), }, { input: [2]float64{math.NaN(), 5}, - want: math.NaN(), }, { input: [2]float64{-3, math.NaN()}, - want: 3, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Copysign(test.input[0], test.input[1]) got := Copysign(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) @@ -360,7 +359,7 @@ func TestDim(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Dim(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -381,7 +380,7 @@ func TestDim(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Dim(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -402,7 +401,7 @@ func TestDim(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Dim(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -420,128 +419,63 @@ func TestDim(t *testing.T) { want: 0, }, { - input: [2]float32{Inf[float32](1), Inf[float32](1)}, - want: NaN[float32](), + input: [2]float32{Inf32(1), Inf32(1)}, + want: NaN32(), }, { - input: [2]float32{Inf[float32](-1), Inf[float32](-1)}, - want: NaN[float32](), + input: [2]float32{Inf32(-1), Inf32(-1)}, + want: NaN32(), }, { - input: [2]float32{NaN[float32](), 1}, - want: NaN[float32](), + input: [2]float32{NaN32(), 1}, + want: NaN32(), + }, + { + input: [2]float32{1, NaN32()}, + want: NaN32(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Dim(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input [2]float64 - want float64 }{ { input: [2]float64{4, -2}, - want: 6, }, { input: [2]float64{-4, 2}, - want: 0, }, { input: [2]float64{math.Inf(1), math.Inf(1)}, - want: math.NaN(), }, { input: [2]float64{math.Inf(-1), math.Inf(-1)}, - want: math.NaN(), }, { input: [2]float64{math.NaN(), 1}, - want: math.NaN(), + }, + { + input: [2]float64{1, math.NaN()}, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Dim(test.input[0], test.input[1]) got := Dim(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) } func TestIsInf(t *testing.T) { - t.Run("myInt", func(t *testing.T) { - tests := []struct { - x myInt - sign int - want bool - }{ - { - x: 1, - sign: 1, - want: false, - }, - } - for _, test := range tests { - t.Run(fmt.Sprint(test.x, test.sign), func(t *testing.T) { - got := IsInf(test.x, test.sign) - assert.Equal(t, test.want, got, "expected result to be equal") - }) - } - }) - t.Run("int", func(t *testing.T) { - tests := []struct { - x int - sign int - want bool - }{ - { - x: math.MaxInt, - sign: 1, - want: false, - }, - { - x: math.MinInt, - sign: -1, - want: false, - }, - } - for _, test := range tests { - t.Run(fmt.Sprint(test.x, test.sign), func(t *testing.T) { - got := IsInf(test.x, test.sign) - assert.Equal(t, test.want, got, "expected result to be equal") - }) - } - }) - t.Run("int64", func(t *testing.T) { - tests := []struct { - x int64 - sign int - want bool - }{ - { - x: math.MaxInt64, - sign: 1, - want: false, - }, - { - x: math.MinInt64, - sign: -1, - want: false, - }, - } - for _, test := range tests { - t.Run(fmt.Sprint(test.x, test.sign), func(t *testing.T) { - got := IsInf(test.x, test.sign) - assert.Equal(t, test.want, got, "expected result to be equal") - }) - } - }) t.Run("float32", func(t *testing.T) { tests := []struct { x float32 @@ -554,22 +488,22 @@ func TestIsInf(t *testing.T) { want: false, }, { - x: Inf[float32](1), + x: Inf32(1), sign: -1, want: false, }, { - x: Inf[float32](-1), + x: Inf32(-1), sign: 1, want: false, }, { - x: Inf[float32](1), + x: Inf32(1), sign: 1, want: true, }, { - x: Inf[float32](-1), + x: Inf32(-1), sign: -1, want: true, }, @@ -577,7 +511,9 @@ func TestIsInf(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.x, test.sign), func(t *testing.T) { got := IsInf(test.x, test.sign) - assert.Equal(t, test.want, got, "expected result to be equal") + if test.want != got { + t.Errorf("want %v, got %v", test.want, got) + } }) } }) @@ -585,38 +521,35 @@ func TestIsInf(t *testing.T) { tests := []struct { x float64 sign int - want bool }{ { x: 1.0, sign: 1, - want: false, }, { x: math.Inf(1), sign: -1, - want: false, }, { x: math.Inf(-1), sign: 1, - want: false, }, { x: math.Inf(1), sign: 1, - want: true, }, { x: math.Inf(-1), sign: -1, - want: true, }, } for _, test := range tests { t.Run(fmt.Sprint(test.x, test.sign), func(t *testing.T) { + want := math.IsInf(test.x, test.sign) got := IsInf(test.x, test.sign) - assert.Equal(t, test.want, got, "expected result to be equal") + if want != got { + t.Errorf("want %v, got %v", want, got) + } }) } }) @@ -636,7 +569,9 @@ func TestIsNaN(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := IsNaN(test.input) - assert.Equal(t, test.want, got, "expected result to be equal") + if test.want != got { + t.Errorf("want %v, got %v", test.want, got) + } }) } }) @@ -653,7 +588,9 @@ func TestIsNaN(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := IsNaN(test.input) - assert.Equal(t, test.want, got, "expected result to be equal") + if test.want != got { + t.Errorf("want %v, got %v", test.want, got) + } }) } }) @@ -670,7 +607,9 @@ func TestIsNaN(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := IsNaN(test.input) - assert.Equal(t, test.want, got, "expected result to be equal") + if test.want != got { + t.Errorf("want %v, got %v", test.want, got) + } }) } }) @@ -687,7 +626,9 @@ func TestIsNaN(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := IsNaN(test.input) - assert.Equal(t, test.want, got, "expected result to be equal") + if test.want != got { + t.Errorf("want %v, got %v", test.want, got) + } }) } }) @@ -704,7 +645,9 @@ func TestIsNaN(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := IsNaN(test.input) - assert.Equal(t, test.want, got, "expected result to be equal") + if test.want != got { + t.Errorf("want %v, got %v", test.want, got) + } }) } }) @@ -718,35 +661,37 @@ func TestIsNaN(t *testing.T) { want: false, }, { - input: NaN[float32](), + input: NaN32(), want: true, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := IsNaN(test.input) - assert.Equal(t, test.want, got, "expected result to be equal") + if test.want != got { + t.Errorf("want %v, got %v", test.want, got) + } }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input float64 - want bool }{ { input: 1, - want: false, }, { input: math.NaN(), - want: true, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.IsNaN(test.input) got := IsNaN(test.input) - assert.Equal(t, test.want, got, "expected result to be equal") + if want != got { + t.Errorf("want %v, got %v", want, got) + } }) } }) @@ -766,7 +711,7 @@ func TestLog(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -791,7 +736,7 @@ func TestLog(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -820,7 +765,7 @@ func TestLog(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -841,7 +786,7 @@ func TestLog(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -866,7 +811,7 @@ func TestLog(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -880,7 +825,7 @@ func TestLog(t *testing.T) { want: 2.302585092994046, }, { - input: Inf[float32](1), + input: Inf32(1), want: math.Inf(1), }, { @@ -888,43 +833,39 @@ func TestLog(t *testing.T) { want: math.Inf(-1), }, { - input: NaN[float32](), + input: NaN32(), want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input float64 - want float64 }{ { input: 10, - want: 2.302585092994046, }, { input: math.Inf(1), - want: math.Inf(1), }, { input: 0, - want: math.Inf(-1), }, { input: math.NaN(), - want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Log(test.input) got := Log(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) @@ -944,7 +885,7 @@ func TestLog10(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log10(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -969,7 +910,7 @@ func TestLog10(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log10(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -998,7 +939,7 @@ func TestLog10(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log10(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1019,7 +960,7 @@ func TestLog10(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log10(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1044,7 +985,7 @@ func TestLog10(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log10(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1058,7 +999,7 @@ func TestLog10(t *testing.T) { want: 1, }, { - input: Inf[float32](1), + input: Inf32(1), want: math.Inf(1), }, { @@ -1066,43 +1007,39 @@ func TestLog10(t *testing.T) { want: math.Inf(-1), }, { - input: NaN[float32](), + input: NaN32(), want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log10(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input float64 - want float64 }{ { input: 10, - want: 1, }, { input: math.Inf(1), - want: math.Inf(1), }, { input: 0, - want: math.Inf(-1), }, { input: math.NaN(), - want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Log10(test.input) got := Log10(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) @@ -1122,7 +1059,7 @@ func TestLog1p(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log1p(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1147,7 +1084,7 @@ func TestLog1p(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log1p(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1176,7 +1113,7 @@ func TestLog1p(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log1p(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1197,7 +1134,7 @@ func TestLog1p(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log1p(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1218,7 +1155,7 @@ func TestLog1p(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log1p(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1244,55 +1181,56 @@ func TestLog1p(t *testing.T) { want: math.NaN(), }, { - input: Inf[float32](1), + input: Inf32(-1), + want: math.NaN(), + }, + { + input: Inf32(1), want: math.Inf(1), }, { - input: NaN[float32](), + input: NaN32(), want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log1p(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input float64 - want float64 }{ { input: 10, - want: 2.3978952727983707, }, { input: 0, - want: 0, }, { input: -1, - want: math.Inf(-1), }, { input: -2, - want: math.NaN(), + }, + { + input: math.Inf(-1), }, { input: math.Inf(1), - want: math.Inf(1), }, { input: math.NaN(), - want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Log1p(test.input) got := Log1p(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) @@ -1312,7 +1250,7 @@ func TestLog2(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log2(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1337,7 +1275,7 @@ func TestLog2(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log2(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1362,7 +1300,7 @@ func TestLog2(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log2(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1383,7 +1321,7 @@ func TestLog2(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log2(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1404,7 +1342,7 @@ func TestLog2(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log2(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1418,7 +1356,7 @@ func TestLog2(t *testing.T) { want: 3.321928094887362, }, { - input: Inf[float32](1), + input: Inf32(1), want: math.Inf(1), }, { @@ -1426,172 +1364,174 @@ func TestLog2(t *testing.T) { want: math.Inf(-1), }, { - input: NaN[float32](), + input: NaN32(), want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Log2(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input float64 - want float64 }{ { input: 10, - want: 3.321928094887362, }, { input: math.Inf(1), - want: math.Inf(1), }, { input: 0, - want: math.Inf(-1), }, { input: math.NaN(), - want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Log2(test.input) got := Log2(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) } func TestLogb(t *testing.T) { - t.Run("int", func(t *testing.T) { + t.Run("float32", func(t *testing.T) { tests := []struct { - input int - want float64 + input float32 + want float32 }{ { input: 10, want: 3, }, - } - for _, test := range tests { - t.Run(fmt.Sprint(test.input), func(t *testing.T) { - got := Logb(test.input) - eqOrNaN(t, test.want, got) - }) - } - }) - t.Run("int64", func(t *testing.T) { - tests := []struct { - input int64 - want float64 - }{ { - input: 10, - want: 3, + input: 9999.0000098765, + want: 13, }, - } - for _, test := range tests { - t.Run(fmt.Sprint(test.input), func(t *testing.T) { - got := Logb(test.input) - eqOrNaN(t, test.want, got) - }) - } - }) - t.Run("uint", func(t *testing.T) { - tests := []struct { - input uint - want float64 - }{ { - input: 10, - want: 3, + input: Inf32(1), + want: Inf32(1), + }, + { + input: Inf32(-1), + want: Inf32(1), + }, + { + input: 0, + want: Inf32(-1), + }, + { + input: NaN32(), + want: NaN32(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Logb(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) - t.Run("uint64", func(t *testing.T) { + t.Run("float64", func(t *testing.T) { tests := []struct { - input uint64 - want float64 + input float64 }{ { input: 10, - want: 3, + }, + { + input: 9999.0000098765, + }, + { + input: math.Inf(1), + }, + { + input: math.Inf(-1), + }, + { + input: 0, + }, + { + input: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Logb(test.input) got := Logb(test.input) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) +} + +func TestIlogb(t *testing.T) { t.Run("float32", func(t *testing.T) { tests := []struct { input float32 - want float64 + want int }{ { input: 10, want: 3, }, { - input: Inf[float32](1), - want: math.Inf(1), + input: 9999.0000098765, + want: 13, + }, + { + input: Inf32(1), + want: math.MaxInt32, }, { input: 0, - want: math.Inf(-1), + want: math.MinInt32, }, { - input: NaN[float32](), - want: math.NaN(), + input: NaN32(), + want: math.MaxInt32, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { - got := Logb(test.input) - eqOrNaN(t, test.want, got) + got := Ilogb(test.input) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input float64 - want float64 }{ { input: 10, - want: 3, + }, + { + input: 9999.0000098765, }, { input: math.Inf(1), - want: math.Inf(1), }, { input: 0, - want: math.Inf(-1), }, { input: math.NaN(), - want: math.NaN(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { - got := Logb(test.input) - eqOrNaN(t, test.want, got) + want := math.Ilogb(test.input) + got := Ilogb(test.input) + assertEqual(t, want, got) }) } }) @@ -1611,7 +1551,7 @@ func TestMax(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Max(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1640,7 +1580,7 @@ func TestMax(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Max(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1669,7 +1609,7 @@ func TestMax(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Max(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1694,7 +1634,7 @@ func TestMax(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Max(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1719,7 +1659,7 @@ func TestMax(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Max(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1737,63 +1677,85 @@ func TestMax(t *testing.T) { want: -1, }, { - input: [2]float32{Inf[float32](1), 1}, - want: Inf[float32](1), + input: [2]float32{Inf32(1), 1}, + want: Inf32(1), + }, + { + input: [2]float32{Inf32(1), math.MaxFloat32}, + want: Inf32(1), + }, + { + input: [2]float32{Inf32(1), NaN32()}, + want: Inf32(1), + }, + { + input: [2]float32{NaN32(), Inf32(1)}, + want: Inf32(1), }, { - input: [2]float32{NaN[float32](), 1}, - want: NaN[float32](), + input: [2]float32{NaN32(), 1}, + want: NaN32(), }, { - input: [2]float32{-0, 0}, + input: [2]float32{negzero32(), 0}, want: 0, }, { - input: [2]float32{-0, -0}, - want: -0, + input: [2]float32{0, negzero32()}, + want: 0, + }, + { + input: [2]float32{negzero32(), negzero32()}, + want: negzero32(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Max(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input [2]float64 - want float64 }{ { input: [2]float64{3.2, 1}, - want: 3.2, }, { input: [2]float64{-3.2, -1}, - want: -1, }, { input: [2]float64{math.Inf(1), 1}, - want: math.Inf(1), + }, + { + input: [2]float64{math.Inf(1), math.MaxFloat64}, + }, + { + input: [2]float64{math.Inf(1), math.NaN()}, + }, + { + input: [2]float64{math.NaN(), math.Inf(1)}, }, { input: [2]float64{math.NaN(), 1}, - want: math.NaN(), }, { - input: [2]float64{-0, 0}, - want: 0, + input: [2]float64{negzero64(), 0}, }, { - input: [2]float64{-0, -0}, - want: -0, + input: [2]float64{0, negzero64()}, + }, + { + input: [2]float64{negzero64(), negzero64()}, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Max(test.input[0], test.input[1]) got := Max(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) @@ -1813,7 +1775,7 @@ func TestMin(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Min(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1842,7 +1804,7 @@ func TestMin(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Min(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1871,7 +1833,7 @@ func TestMin(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Min(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1896,7 +1858,7 @@ func TestMin(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Min(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1921,7 +1883,7 @@ func TestMin(t *testing.T) { for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Min(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) @@ -1939,68 +1901,132 @@ func TestMin(t *testing.T) { want: -3.2, }, { - input: [2]float32{Inf[float32](-1), 1}, - want: Inf[float32](-1), + input: [2]float32{Inf32(-1), 1}, + want: Inf32(-1), + }, + { + input: [2]float32{Inf32(-1), -math.MaxFloat32}, + want: Inf32(-1), + }, + { + input: [2]float32{Inf32(-1), NaN32()}, + want: Inf32(-1), + }, + { + input: [2]float32{NaN32(), Inf32(-1)}, + want: Inf32(-1), }, { - input: [2]float32{NaN[float32](), 1}, - want: NaN[float32](), + input: [2]float32{NaN32(), 1}, + want: NaN32(), }, { - input: [2]float32{-0, 0}, - want: -0, + input: [2]float32{negzero32(), 0}, + want: negzero32(), + }, + { + input: [2]float32{0, negzero32()}, + want: negzero32(), + }, + { + input: [2]float32{negzero32(), negzero32()}, + want: negzero32(), }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { got := Min(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, test.want, got) }) } }) t.Run("float64", func(t *testing.T) { tests := []struct { input [2]float64 - want float64 }{ { input: [2]float64{3.2, 1}, - want: 1, }, { input: [2]float64{-3.2, -1}, - want: -3.2, }, { input: [2]float64{math.Inf(-1), 1}, - want: math.Inf(-1), + }, + { + input: [2]float64{math.Inf(-1), -math.MaxFloat64}, + }, + { + input: [2]float64{math.Inf(-1), math.NaN()}, + }, + { + input: [2]float64{math.NaN(), math.Inf(-1)}, }, { input: [2]float64{math.NaN(), 1}, - want: math.NaN(), }, { input: [2]float64{-0, 0}, - want: -0, }, } for _, test := range tests { t.Run(fmt.Sprint(test.input), func(t *testing.T) { + want := math.Min(test.input[0], test.input[1]) got := Min(test.input[0], test.input[1]) - eqOrNaN(t, test.want, got) + assertEqual(t, want, got) }) } }) } -func eqOrNaN[T Ints | Uints | Floats](t *testing.T, want, got T) { +func assertEqual(t *testing.T, want, got any) { t.Helper() - // Float value NaN is not equal to itself. Test that NaN is NaN - // using IsNaN instead of checking for equality. - if math.IsNaN(float64(want)) { - assert.Truef(t, math.IsNaN(float64(got)), "expected NaN, got %v", got) - } else { - assert.Equal(t, want, got, "expected result to be equal") + switch want := want.(type) { + case float32: + wantBits := math.Float32bits(want) + gotBits := math.Float32bits(got.(float32)) + if wantBits != gotBits { + t.Errorf( + "want float32 %v (%0x), got float32 %v (%0x)", + want, + wantBits, + got, + gotBits) + } + case float64: + wantBits := math.Float64bits(want) + gotBits := math.Float64bits(got.(float64)) + if wantBits != gotBits { + t.Errorf( + "want float64 %v (%0x), got float64 %v (%0x)", + want, + wantBits, + got, + gotBits) + } + default: + if want != got { + t.Errorf("want %v, got %v", want, got) + } + } +} + +func TestInf32(t *testing.T) { + pi := Inf32(1) + if !math.IsInf(float64(pi), 1) { + t.Errorf("want +Inf, got %v (%0x)", pi, math.Float32bits(pi)) + } + + ni := Inf32(-1) + if !math.IsInf(float64(ni), -1) { + t.Errorf("want -Inf, got %v (%0x)", ni, math.Float32bits(ni)) + } +} + +func TestNaN32(t *testing.T) { + nan := NaN32() + if !math.IsNaN(float64(nan)) { + t.Errorf("want NaN, got %v (%0x)", nan, math.Float32bits(nan)) } } diff --git a/go.mod b/go.mod index dfe83f2..d400212 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,3 @@ module github.com/matthewdale/gmath -// TODO: go 1.18 go 1.18 - -require github.com/stretchr/testify v1.7.0 - -require ( - github.com/davecgh/go-spew v1.1.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect -) diff --git a/go.sum b/go.sum index acb88a4..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=