1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package s1
16
17 import (
18 "math"
19 "testing"
20 )
21
22
23 func float64Eq(x, y float64) bool {
24 return float64Near(x, y, epsilon)
25 }
26
27
28 func float64Near(x, y, eps float64) bool {
29 return math.Abs(x-y) <= eps
30 }
31
32 func TestEmptyValue(t *testing.T) {
33 var a Angle
34 if rad := a.Radians(); rad != 0 {
35 t.Errorf("Empty value of Angle was %v, want 0", rad)
36 }
37 }
38
39 func TestPiRadiansExactly180Degrees(t *testing.T) {
40 if rad := (math.Pi * Radian).Radians(); rad != math.Pi {
41 t.Errorf("(π * Radian).Radians() was %v, want π", rad)
42 }
43 if deg := (math.Pi * Radian).Degrees(); deg != 180 {
44 t.Errorf("(π * Radian).Degrees() was %v, want 180", deg)
45 }
46 if rad := (180 * Degree).Radians(); rad != math.Pi {
47 t.Errorf("(180 * Degree).Radians() was %v, want π", rad)
48 }
49 if deg := (180 * Degree).Degrees(); deg != 180 {
50 t.Errorf("(180 * Degree).Degrees() was %v, want 180", deg)
51 }
52
53 if deg := (math.Pi / 2 * Radian).Degrees(); deg != 90 {
54 t.Errorf("(π/2 * Radian).Degrees() was %v, want 90", deg)
55 }
56
57
58 if deg := (-math.Pi / 2 * Radian).Degrees(); deg != -90 {
59 t.Errorf("(-π/2 * Radian).Degrees() was %v, want -90", deg)
60 }
61 if rad := (-45 * Degree).Radians(); rad != -math.Pi/4 {
62 t.Errorf("(-45 * Degree).Radians() was %v, want -π/4", rad)
63 }
64 }
65
66 func TestE5E6E7Representation(t *testing.T) {
67
68 exp, act := (-45 * Degree).Radians(), (-4500000 * E5).Radians()
69 if math.Abs(exp-act) > 1e-15 {
70 t.Errorf("(-4500000 * E5).Radians() was %v, want %v", act, exp)
71 }
72 if exp, act := (-60 * Degree).Radians(), (-60000000 * E6).Radians(); exp != act {
73 t.Errorf("(-60000000 * E6).Radians() was %v, want %v", act, exp)
74 }
75 if exp, act := (75 * Degree).Radians(), (750000000 * E7).Radians(); exp != act {
76 t.Errorf("(-750000000 * E7).Radians() was %v, want %v", act, exp)
77 }
78
79 if exp, act := int32(-17256123), (-172.56123 * Degree).E5(); exp != act {
80 t.Errorf("(-172.56123°).E5() was %v, want %v", act, exp)
81 }
82 if exp, act := int32(12345678), (12.345678 * Degree).E6(); exp != act {
83 t.Errorf("(12.345678°).E6() was %v, want %v", act, exp)
84 }
85 if exp, act := int32(-123456789), (-12.3456789 * Degree).E7(); exp != act {
86 t.Errorf("(-12.3456789°).E7() was %v, want %v", act, exp)
87 }
88
89 roundingTests := []struct {
90 have Angle
91 want int32
92 }{
93 {0.500000001, 1},
94 {-0.500000001, -1},
95 {0.499999999, 0},
96 {-0.499999999, 0},
97 }
98 for _, test := range roundingTests {
99 if act := (test.have * 1e-5 * Degree).E5(); test.want != act {
100 t.Errorf("(%v°).E5() was %v, want %v", test.have, act, test.want)
101 }
102 if act := (test.have * 1e-6 * Degree).E6(); test.want != act {
103 t.Errorf("(%v°).E6() was %v, want %v", test.have, act, test.want)
104 }
105 if act := (test.have * 1e-7 * Degree).E7(); test.want != act {
106 t.Errorf("(%v°).E7() was %v, want %v", test.have, act, test.want)
107 }
108 }
109 }
110
111 func TestNormalizeCorrectlyCanonicalizesAngles(t *testing.T) {
112 tests := []struct {
113 in, want float64
114 }{
115 {360, 0},
116 {-90, -90},
117 {-180, 180},
118 {180, 180},
119 {540, 180},
120 {-270, 90},
121 }
122 for _, test := range tests {
123 deg := (Angle(test.in) * Degree).Normalized().Degrees()
124 if deg != test.want {
125 t.Errorf("Normalized %.0f° = %v, want %v", test.in, deg, test.want)
126 }
127 }
128 }
129
130 func TestAngleString(t *testing.T) {
131 if s, exp := (180 * Degree).String(), "180.0000000"; s != exp {
132 t.Errorf("(180°).String() = %q, want %q", s, exp)
133 }
134 }
135
136 func TestDegreesVsRadians(t *testing.T) {
137
138 for k := -8; k <= 8; k++ {
139 if got, want := Angle(45*k)*Degree, Angle((float64(k)*math.Pi)/4)*Radian; got != want {
140 t.Errorf("45°*%d != (%d*π)/4 radians (%f vs %f)", k, k, got, want)
141 }
142
143 if got, want := (Angle(45*k) * Degree).Degrees(), float64(45*k); got != want {
144 t.Errorf("Angle(45°*%d).Degrees() != 45*%d, (%f vs %f)", k, k, got, want)
145 }
146 }
147
148 for k := uint64(0); k < 30; k++ {
149 m := 1 << k
150 n := float64(m)
151 for _, test := range []struct{ deg, rad float64 }{
152 {180, 1},
153 {60, 3},
154 {36, 5},
155 {20, 9},
156 {4, 45},
157 } {
158 if got, want := Angle(test.deg/n)*Degree, Angle(math.Pi/(test.rad*n))*Radian; got != want {
159 t.Errorf("%v°/%d != π/%v*%d rad (%f vs %f)", test.deg, m, test.rad, m, got, want)
160 }
161 }
162 }
163
164
165 if got := (60 * Degree).Degrees(); float64Eq(got, 60) {
166 t.Errorf("Angle(60).Degrees() == 60, but should not (%f vs %f)", got, 60.0)
167 }
168 }
169
170
171
172
View as plain text