3 // Copyright 2013 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Test division of variables. Generate many test cases,
8 // compute correct answer using shift and subtract,
9 // and then compare against results from division and
12 // Primarily useful for testing software div/mod.
20 // About 3e9 test cases (calls to checkdiv3).
21 // Too long for everyday testing.
22 gen2(3, 64, 2, 64, checkdiv1
)
25 // About 4e6 test cases (calls to checkdiv3).
26 // Runs for 8 seconds on ARM chromebook, much faster elsewhere.
27 gen2(2, 64, 1, 64, checkdiv1
)
31 // generate all uint64 values x where x has at most n bits set in the low w
32 // and call f(x) for each.
33 func gen1(n
, w
int, f
func(uint64)) {
37 func gen(val
uint64, nbits
, maxbits
, pos
int, f
func(uint64)) {
42 gen(val
, nbits
, maxbits
, pos
-1, f
)
44 gen(val|
1<<uint(pos
), nbits
+1, maxbits
, pos
-1, f
)
48 // generate all uint64 values x, y where x has at most n1 bits set in the low w1
49 // and y has at most n2 bits set in the low w2 and call f(x, y) for each.
50 func gen2(n1
, w1
, n2
, w2
int, f
func(uint64, uint64)) {
51 gen1(n1
, w1
, func(x
uint64) {
52 gen1(n2
, w2
, func(y
uint64) {
58 // x and y are uint64s with at most 2 bits set.
59 // Check those values and values above and below,
60 // along with bitwise inversions of the same (done in checkdiv2).
61 func checkdiv1(x
, y
uint64) {
63 // If the low bit is set in x or y, adding or subtracting 1
64 // produces a number that checkdiv1 is going to be called
65 // with anyway, so don't duplicate effort.
82 func checkdiv2(x
, y
uint64) {
91 func checkdiv3(x
, y
uint64) {
93 if ntest
&(ntest
-1) == 0 && long
{
97 if (uint64(uint32(x
)) == x ||
uint64(uint32(^x
)) == ^x
) && (uint64(uint32(y
)) == y ||
uint64(uint32(^y
)) == ^y
) {
98 checkuint32(uint32(x
), uint32(y
))
100 if (uint64(uint16(x
)) == x ||
uint64(uint16(^x
)) == ^x
) && (uint64(uint16(y
)) == y ||
uint64(uint16(^y
)) == ^y
) {
101 checkuint16(uint16(x
), uint16(y
))
103 if (uint64(uint8(x
)) == x ||
uint64(uint8(^x
)) == ^x
) && (uint64(uint8(y
)) == y ||
uint64(uint8(^y
)) == ^y
) {
104 checkuint8(uint8(x
), uint8(y
))
111 if (int64(int32(sx
)) == sx ||
int64(int32(^sx
)) == ^sx
) && (int64(int32(sy
)) == sy ||
int64(int32(^sy
)) == ^sy
) {
112 checkint32(int32(sx
), int32(sy
))
114 if (int64(int16(sx
)) == sx ||
int64(int16(^sx
)) == ^sx
) && (int64(int16(sy
)) == sy ||
int64(int16(^sy
)) == ^sy
) {
115 checkint16(int16(sx
), int16(sy
))
117 if (int64(int8(sx
)) == sx ||
int64(int8(^sx
)) == ^sx
) && (int64(int8(sy
)) == sy ||
int64(int8(^sy
)) == ^sy
) {
118 checkint8(int8(sx
), int8(sy
))
122 // Check result of x/y, x%y for various types.
124 func checkuint(x
, y
uint) {
130 q
, r
:= udiv(uint64(x
), uint64(y
))
134 print("uint(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
137 print("uint(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
141 func checkuint64(x
, y
uint64) {
151 print("uint64(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
154 print("uint64(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
158 func checkuint32(x
, y
uint32) {
164 q
, r
:= udiv(uint64(x
), uint64(y
))
168 print("uint32(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
171 print("uint32(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
175 func checkuint16(x
, y
uint16) {
181 q
, r
:= udiv(uint64(x
), uint64(y
))
185 print("uint16(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
188 print("uint16(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
192 func checkuint8(x
, y
uint8) {
198 q
, r
:= udiv(uint64(x
), uint64(y
))
202 print("uint8(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
205 print("uint8(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
209 func checkint(x
, y
int) {
215 q
, r
:= idiv(int64(x
), int64(y
))
219 print("int(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
222 print("int(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
226 func checkint64(x
, y
int64) {
236 print("int64(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
239 print("int64(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
243 func checkint32(x
, y
int32) {
249 q
, r
:= idiv(int64(x
), int64(y
))
253 print("int32(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
256 print("int32(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
260 func checkint16(x
, y
int16) {
266 q
, r
:= idiv(int64(x
), int64(y
))
270 print("int16(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
273 print("int16(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
277 func checkint8(x
, y
int8) {
283 q
, r
:= idiv(int64(x
), int64(y
))
287 print("int8(", x
, "/", y
, ") = ", q1
, ", want ", q
, "\n")
290 print("int8(", x
, "%", y
, ") = ", r1
, ", want ", r
, "\n")
294 func divzerouint(x
, y
uint) uint {
295 defer checkudivzero("uint", uint64(x
))
299 func divzerouint64(x
, y
uint64) uint64 {
300 defer checkudivzero("uint64", uint64(x
))
304 func divzerouint32(x
, y
uint32) uint32 {
305 defer checkudivzero("uint32", uint64(x
))
309 func divzerouint16(x
, y
uint16) uint16 {
310 defer checkudivzero("uint16", uint64(x
))
314 func divzerouint8(x
, y
uint8) uint8 {
315 defer checkudivzero("uint8", uint64(x
))
319 func checkudivzero(typ
string, x
uint64) {
320 if recover() == nil {
321 print(typ
, "(", x
, " / 0) did not panic")
325 func divzeroint(x
, y
int) int {
326 defer checkdivzero("int", int64(x
))
330 func divzeroint64(x
, y
int64) int64 {
331 defer checkdivzero("int64", int64(x
))
335 func divzeroint32(x
, y
int32) int32 {
336 defer checkdivzero("int32", int64(x
))
340 func divzeroint16(x
, y
int16) int16 {
341 defer checkdivzero("int16", int64(x
))
345 func divzeroint8(x
, y
int8) int8 {
346 defer checkdivzero("int8", int64(x
))
350 func checkdivzero(typ
string, x
int64) {
351 if recover() == nil {
352 print(typ
, "(", x
, " / 0) did not panic")
356 func modzerouint(x
, y
uint) uint {
357 defer checkumodzero("uint", uint64(x
))
361 func modzerouint64(x
, y
uint64) uint64 {
362 defer checkumodzero("uint64", uint64(x
))
366 func modzerouint32(x
, y
uint32) uint32 {
367 defer checkumodzero("uint32", uint64(x
))
371 func modzerouint16(x
, y
uint16) uint16 {
372 defer checkumodzero("uint16", uint64(x
))
376 func modzerouint8(x
, y
uint8) uint8 {
377 defer checkumodzero("uint8", uint64(x
))
381 func checkumodzero(typ
string, x
uint64) {
382 if recover() == nil {
383 print(typ
, "(", x
, " % 0) did not panic")
387 func modzeroint(x
, y
int) int {
388 defer checkmodzero("int", int64(x
))
392 func modzeroint64(x
, y
int64) int64 {
393 defer checkmodzero("int64", int64(x
))
397 func modzeroint32(x
, y
int32) int32 {
398 defer checkmodzero("int32", int64(x
))
402 func modzeroint16(x
, y
int16) int16 {
403 defer checkmodzero("int16", int64(x
))
407 func modzeroint8(x
, y
int8) int8 {
408 defer checkmodzero("int8", int64(x
))
412 func checkmodzero(typ
string, x
int64) {
413 if recover() == nil {
414 print(typ
, "(", x
, " % 0) did not panic")
418 // unsigned divide and mod using shift and subtract.
419 func udiv(x
, y
uint64) (q
, r
uint64) {
421 for y
+y
> y
&& y
+y
<= x
{
425 for ; sh
>= 0; sh
-- {
436 // signed divide and mod: do unsigned and adjust signs.
437 func idiv(x
, y
int64) (q
, r
int64) {
438 // special case for minint / -1 = minint
439 if x
-1 > x
&& y
== -1 {
450 uq
, ur
:= udiv(ux
, uy
)
456 if (x
< 0) != (y
< 0) {