mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 08:40:55 +00:00 
			
		
		
		
	 53fd522c0d
			
		
	
	
		53fd522c0d
		
	
	
	
	
		
			
			Follows suit with https://go-review.googlesource.com/#/c/20111. Generated by running $ grep -R 'Go Authors. All' * | cut -d":" -f1 | while read F;do perl -pi -e 's/Go Authors. All/Go Authors. All/g' $F;done The code in cmd/internal/unvendor wasn't changed. Fixes #15213 Change-Id: I4f235cee0a62ec435f9e8540a1ec08ae03b1a75f Reviewed-on: https://go-review.googlesource.com/21819 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
		
			
				
	
	
		
			460 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			460 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // run
 | |
| 
 | |
| // Copyright 2013 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.
 | |
| 
 | |
| // Test division of variables. Generate many test cases,
 | |
| // compute correct answer using shift and subtract,
 | |
| // and then compare against results from division and
 | |
| // modulus operators.
 | |
| //
 | |
| // Primarily useful for testing software div/mod.
 | |
| 
 | |
| package main
 | |
| 
 | |
| const long = false
 | |
| 
 | |
| func main() {
 | |
| 	if long {
 | |
| 		// About 3e9 test cases (calls to checkdiv3).
 | |
| 		// Too long for everyday testing.
 | |
| 		gen2(3, 64, 2, 64, checkdiv1)
 | |
| 		println(ntest)
 | |
| 	} else {
 | |
| 		// About 4e6 test cases (calls to checkdiv3).
 | |
| 		// Runs for 8 seconds on ARM chromebook, much faster elsewhere.
 | |
| 		gen2(2, 64, 1, 64, checkdiv1)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // generate all uint64 values x where x has at most n bits set in the low w
 | |
| // and call f(x) for each.
 | |
| func gen1(n, w int, f func(uint64)) {
 | |
| 	gen(0, 0, n, w-1, f)
 | |
| }
 | |
| 
 | |
| func gen(val uint64, nbits, maxbits, pos int, f func(uint64)) {
 | |
| 	if pos < 0 {
 | |
| 		f(val)
 | |
| 		return
 | |
| 	}
 | |
| 	gen(val, nbits, maxbits, pos-1, f)
 | |
| 	if nbits < maxbits {
 | |
| 		gen(val|1<<uint(pos), nbits+1, maxbits, pos-1, f)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // generate all uint64 values x, y where x has at most n1 bits set in the low w1
 | |
| // and y has at most n2 bits set in the low w2 and call f(x, y) for each.
 | |
| func gen2(n1, w1, n2, w2 int, f func(uint64, uint64)) {
 | |
| 	gen1(n1, w1, func(x uint64) {
 | |
| 		gen1(n2, w2, func(y uint64) {
 | |
| 			f(x, y)
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // x and y are uint64s with at most 2 bits set.
 | |
| // Check those values and values above and below,
 | |
| // along with bitwise inversions of the same (done in checkdiv2).
 | |
| func checkdiv1(x, y uint64) {
 | |
| 	checkdiv2(x, y)
 | |
| 	// If the low bit is set in x or y, adding or subtracting 1
 | |
| 	// produces a number that checkdiv1 is going to be called
 | |
| 	// with anyway, so don't duplicate effort.
 | |
| 	if x&1 == 0 {
 | |
| 		checkdiv2(x+1, y)
 | |
| 		checkdiv2(x-1, y)
 | |
| 	}
 | |
| 	if y&1 == 0 {
 | |
| 		checkdiv2(x, y-1)
 | |
| 		checkdiv2(x, y+1)
 | |
| 		if x&1 == 0 {
 | |
| 			checkdiv2(x+1, y-1)
 | |
| 			checkdiv2(x-1, y-1)
 | |
| 			checkdiv2(x-1, y+1)
 | |
| 			checkdiv2(x+1, y+1)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkdiv2(x, y uint64) {
 | |
| 	checkdiv3(x, y)
 | |
| 	checkdiv3(^x, y)
 | |
| 	checkdiv3(x, ^y)
 | |
| 	checkdiv3(^x, ^y)
 | |
| }
 | |
| 
 | |
| var ntest int64 = 0
 | |
| 
 | |
| func checkdiv3(x, y uint64) {
 | |
| 	ntest++
 | |
| 	if ntest&(ntest-1) == 0 && long {
 | |
| 		println(ntest, "...")
 | |
| 	}
 | |
| 	checkuint64(x, y)
 | |
| 	if (uint64(uint32(x)) == x || uint64(uint32(^x)) == ^x) && (uint64(uint32(y)) == y || uint64(uint32(^y)) == ^y) {
 | |
| 		checkuint32(uint32(x), uint32(y))
 | |
| 	}
 | |
| 	if (uint64(uint16(x)) == x || uint64(uint16(^x)) == ^x) && (uint64(uint16(y)) == y || uint64(uint16(^y)) == ^y) {
 | |
| 		checkuint16(uint16(x), uint16(y))
 | |
| 	}
 | |
| 	if (uint64(uint8(x)) == x || uint64(uint8(^x)) == ^x) && (uint64(uint8(y)) == y || uint64(uint8(^y)) == ^y) {
 | |
| 		checkuint8(uint8(x), uint8(y))
 | |
| 	}
 | |
| 	
 | |
| 	
 | |
| 	sx := int64(x)
 | |
| 	sy := int64(y)
 | |
| 	checkint64(sx, sy)
 | |
| 	if (int64(int32(sx)) == sx || int64(int32(^sx)) == ^sx) && (int64(int32(sy)) == sy || int64(int32(^sy)) == ^sy) {
 | |
| 		checkint32(int32(sx), int32(sy))
 | |
| 	}
 | |
| 	if (int64(int16(sx)) == sx || int64(int16(^sx)) == ^sx) && (int64(int16(sy)) == sy || int64(int16(^sy)) == ^sy) {
 | |
| 		checkint16(int16(sx), int16(sy))
 | |
| 	}
 | |
| 	if (int64(int8(sx)) == sx || int64(int8(^sx)) == ^sx) && (int64(int8(sy)) == sy || int64(int8(^sy)) == ^sy) {
 | |
| 		checkint8(int8(sx), int8(sy))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Check result of x/y, x%y for various types.
 | |
| 
 | |
| func checkuint(x, y uint) {
 | |
| 	if y == 0 {
 | |
| 		divzerouint(x, y)
 | |
| 		modzerouint(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := udiv(uint64(x), uint64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != uint(q) {
 | |
| 		print("uint(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != uint(r) {
 | |
| 		print("uint(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkuint64(x, y uint64) {
 | |
| 	if y == 0 {
 | |
| 		divzerouint64(x, y)
 | |
| 		modzerouint64(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := udiv(x, y)
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != q {
 | |
| 		print("uint64(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != r {
 | |
| 		print("uint64(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkuint32(x, y uint32) {
 | |
| 	if y == 0 {
 | |
| 		divzerouint32(x, y)
 | |
| 		modzerouint32(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := udiv(uint64(x), uint64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != uint32(q) {
 | |
| 		print("uint32(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != uint32(r) {
 | |
| 		print("uint32(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkuint16(x, y uint16) {
 | |
| 	if y == 0 {
 | |
| 		divzerouint16(x, y)
 | |
| 		modzerouint16(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := udiv(uint64(x), uint64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != uint16(q) {
 | |
| 		print("uint16(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != uint16(r) {
 | |
| 		print("uint16(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkuint8(x, y uint8) {
 | |
| 	if y == 0 {
 | |
| 		divzerouint8(x, y)
 | |
| 		modzerouint8(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := udiv(uint64(x), uint64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != uint8(q) {
 | |
| 		print("uint8(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != uint8(r) {
 | |
| 		print("uint8(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkint(x, y int) {
 | |
| 	if y == 0 {
 | |
| 		divzeroint(x, y)
 | |
| 		modzeroint(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := idiv(int64(x), int64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != int(q) {
 | |
| 		print("int(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != int(r) {
 | |
| 		print("int(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkint64(x, y int64) {
 | |
| 	if y == 0 {
 | |
| 		divzeroint64(x, y)
 | |
| 		modzeroint64(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := idiv(x, y)
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != q {
 | |
| 		print("int64(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != r {
 | |
| 		print("int64(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkint32(x, y int32) {
 | |
| 	if y == 0 {
 | |
| 		divzeroint32(x, y)
 | |
| 		modzeroint32(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := idiv(int64(x), int64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != int32(q) {
 | |
| 		print("int32(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != int32(r) {
 | |
| 		print("int32(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkint16(x, y int16) {
 | |
| 	if y == 0 {
 | |
| 		divzeroint16(x, y)
 | |
| 		modzeroint16(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := idiv(int64(x), int64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != int16(q) {
 | |
| 		print("int16(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != int16(r) {
 | |
| 		print("int16(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func checkint8(x, y int8) {
 | |
| 	if y == 0 {
 | |
| 		divzeroint8(x, y)
 | |
| 		modzeroint8(x, y)
 | |
| 		return
 | |
| 	}
 | |
| 	q, r := idiv(int64(x), int64(y))
 | |
| 	q1 := x/y
 | |
| 	r1 := x%y
 | |
| 	if q1 != int8(q) {
 | |
| 		print("int8(", x, "/", y, ") = ", q1, ", want ", q, "\n")
 | |
| 	}
 | |
| 	if r1 != int8(r) {
 | |
| 		print("int8(", x, "%", y, ") = ", r1, ", want ", r, "\n")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func divzerouint(x, y uint) uint {
 | |
| 	defer checkudivzero("uint", uint64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzerouint64(x, y uint64) uint64 {
 | |
| 	defer checkudivzero("uint64", uint64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzerouint32(x, y uint32) uint32 {
 | |
| 	defer checkudivzero("uint32", uint64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzerouint16(x, y uint16) uint16 {
 | |
| 	defer checkudivzero("uint16", uint64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzerouint8(x, y uint8) uint8 {
 | |
| 	defer checkudivzero("uint8", uint64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func checkudivzero(typ string, x uint64) {
 | |
| 	if recover() == nil {
 | |
| 		print(typ, "(", x, " / 0) did not panic")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func divzeroint(x, y int) int {
 | |
| 	defer checkdivzero("int", int64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzeroint64(x, y int64) int64 {
 | |
| 	defer checkdivzero("int64", int64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzeroint32(x, y int32) int32 {
 | |
| 	defer checkdivzero("int32", int64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzeroint16(x, y int16) int16 {
 | |
| 	defer checkdivzero("int16", int64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func divzeroint8(x, y int8) int8 {
 | |
| 	defer checkdivzero("int8", int64(x))
 | |
| 	return x / y
 | |
| }
 | |
| 
 | |
| func checkdivzero(typ string, x int64) {
 | |
| 	if recover() == nil {
 | |
| 		print(typ, "(", x, " / 0) did not panic")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func modzerouint(x, y uint) uint {
 | |
| 	defer checkumodzero("uint", uint64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzerouint64(x, y uint64) uint64 {
 | |
| 	defer checkumodzero("uint64", uint64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzerouint32(x, y uint32) uint32 {
 | |
| 	defer checkumodzero("uint32", uint64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzerouint16(x, y uint16) uint16 {
 | |
| 	defer checkumodzero("uint16", uint64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzerouint8(x, y uint8) uint8 {
 | |
| 	defer checkumodzero("uint8", uint64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func checkumodzero(typ string, x uint64) {
 | |
| 	if recover() == nil {
 | |
| 		print(typ, "(", x, " % 0) did not panic")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func modzeroint(x, y int) int {
 | |
| 	defer checkmodzero("int", int64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzeroint64(x, y int64) int64 {
 | |
| 	defer checkmodzero("int64", int64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzeroint32(x, y int32) int32 {
 | |
| 	defer checkmodzero("int32", int64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzeroint16(x, y int16) int16 {
 | |
| 	defer checkmodzero("int16", int64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func modzeroint8(x, y int8) int8 {
 | |
| 	defer checkmodzero("int8", int64(x))
 | |
| 	return x % y
 | |
| }
 | |
| 
 | |
| func checkmodzero(typ string, x int64) {
 | |
| 	if recover() == nil {
 | |
| 		print(typ, "(", x, " % 0) did not panic")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // unsigned divide and mod using shift and subtract.
 | |
| func udiv(x, y uint64) (q, r uint64) {
 | |
| 	sh := 0
 | |
| 	for y+y > y && y+y <= x {
 | |
| 		sh++
 | |
| 		y <<= 1
 | |
| 	}
 | |
| 	for ; sh >= 0; sh-- {
 | |
| 		q <<= 1
 | |
| 		if x >= y {
 | |
| 			x -= y
 | |
| 			q |= 1
 | |
| 		}
 | |
| 		y >>= 1
 | |
| 	}
 | |
| 	return q, x	
 | |
| }
 | |
| 
 | |
| // signed divide and mod: do unsigned and adjust signs.
 | |
| func idiv(x, y int64) (q, r int64) {
 | |
| 	// special case for minint / -1 = minint
 | |
| 	if x-1 > x && y == -1 {
 | |
| 		return x, 0
 | |
| 	}
 | |
| 	ux := uint64(x)
 | |
| 	uy := uint64(y)
 | |
| 	if x < 0 {
 | |
| 		ux = -ux
 | |
| 	}
 | |
| 	if y < 0 {
 | |
| 		uy = -uy
 | |
| 	}
 | |
| 	uq, ur := udiv(ux, uy)
 | |
| 	q = int64(uq)
 | |
| 	r = int64(ur)
 | |
| 	if x < 0 {
 | |
| 		r = -r
 | |
| 	}
 | |
| 	if (x < 0) != (y < 0) {
 | |
| 		q = -q
 | |
| 	}
 | |
| 	return q, r
 | |
| }
 |