func SqrtShiftU64(x uint64) uint64 { // The highest set bit of the square root of x is equal to // log2(x)/2, and always fits in a 32bit word. Using uint // instead of uint64 guarantees native word width, which // is 7/4 faster on my 32bit netbook. r := uint(1 << (u64.Log2(x) >> 1)) s := r >> 1 t := r + s for s > 0 { if uint64(t)*uint64(t) <= x { r = t } s >>= 1 t = r + s } return uint64(r) }
func TestLog2(t *testing.T) { t.Log("Testing Log2\n") iMax := uint(1) if iMax<<32 == 0 { iMax = 31 } else { iMax = 63 } for i := uint(0); i < iMax; i++ { for j := uint(0); j < i; j++ { k := int((1 << i) + (1 << j)) if intgr.Log2(k) != int(i) { t.Logf("intgr.Log2(%v) == %v\n", k, intgr.Log2(k)) t.FailNow() } } } if intgr.Log2(-1) != -1 { t.Logf("intgr.Log2(-1) == %v\n", intgr.Log2(-1)) t.FailNow() } for i := uint(0); i < iMax; i++ { for j := uint(0); j < i; j++ { k := uint((1 << i) + (1 << j)) if uintgr.Log2(k) != i { t.Logf("intgr.Log2(%v) == %v\n", k, uintgr.Log2(k)) t.Fail() } } } for i := uint32(0); i < uint32(31); i++ { for j := uint32(0); j < i; j++ { k := int32((1 << i) + (1 << j)) if i32.Log2(k) != int32(i) { t.Logf("i32.Log2(%v) == %v\n", k, i32.Log2(k)) t.FailNow() } } } if i32.Log2(-1) != int32(-1) { t.Logf("i32.Log2(-1) == %v\n", i32.Log2(-1)) t.FailNow() } for i := uint32(0); i < uint32(31); i++ { for j := uint32(0); j < i; j++ { k := uint32((1 << i) + (1 << j)) if u32.Log2(k) != i { t.Logf("u32.Log2(%v) == %v\n", k, u32.Log2(k)) t.FailNow() } } } for i := uint64(0); i < uint64(63); i++ { for j := uint64(0); j < i; j++ { k := int64((1 << i) + (1 << j)) if i64.Log2(k) != int64(i) { t.Logf("i64.Log2(%v) == %v\n", k, i64.Log2(k)) t.FailNow() } } } if i64.Log2(-1) != int64(-1) { t.Logf("i64.Log2(-1) == %v\n", i64.Log2(-1)) t.FailNow() } for i := uint64(0); i < uint64(63); i++ { for j := uint64(0); j < i; j++ { k := uint64((1 << i) + (1 << j)) if u64.Log2(k) != i { t.Logf("u64.Log2(%v) == %v\n", k, u64.Log2(k)) t.FailNow() } } } }