1
2
3
4
5 package a
6
7 import (
8 "math"
9 )
10
11 type Numeric interface {
12 ~int | ~int8 | ~int16 | ~int32 | ~int64 |
13 ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
14 ~float32 | ~float64 |
15 ~complex64 | ~complex128
16 }
17
18
19 type numericAbs[T Numeric] interface {
20 ~struct{ Value_ T }
21 Abs() T
22 Value() T
23 }
24
25
26
27 func absDifference[T Numeric, U numericAbs[T]](a, b U) T {
28 d := a.Value() - b.Value()
29 dt := U{Value_: d}
30 return dt.Abs()
31 }
32
33
34 type orderedNumeric interface {
35 ~int | ~int8 | ~int16 | ~int32 | ~int64 |
36 ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
37 ~float32 | ~float64
38 }
39
40
41 type Complex interface {
42 ~complex64 | ~complex128
43 }
44
45
46
47 type orderedAbs[T orderedNumeric] struct {
48 Value_ T
49 }
50
51 func (a orderedAbs[T]) Abs() T {
52 if a.Value_ < 0 {
53 return -a.Value_
54 }
55 return a.Value_
56 }
57
58
59
60
61
62
63 func (a orderedAbs[T]) Value() T {
64 return a.Value_
65 }
66
67
68
69 type complexAbs[T Complex] struct {
70 Value_ T
71 }
72
73 func realimag(x any) (re, im float64) {
74 switch z := x.(type) {
75 case complex64:
76 re = float64(real(z))
77 im = float64(imag(z))
78 case complex128:
79 re = real(z)
80 im = imag(z)
81 default:
82 panic("unknown complex type")
83 }
84 return
85 }
86
87 func (a complexAbs[T]) Abs() T {
88
89 r, i := realimag(a.Value_)
90
91
92 d := math.Sqrt(r*r + i*i)
93 return T(complex(d, 0))
94 }
95
96 func (a complexAbs[T]) Value() T {
97 return a.Value_
98 }
99
100
101
102 func OrderedAbsDifference[T orderedNumeric](a, b T) T {
103 return absDifference(orderedAbs[T]{a}, orderedAbs[T]{b})
104 }
105
106
107
108 func ComplexAbsDifference[T Complex](a, b T) T {
109 return absDifference(complexAbs[T]{a}, complexAbs[T]{b})
110 }
111
View as plain text