github.com/ericlagergren/ctb@v0.0.0-20220810041818-96749d9c394d/xbits/ct/ct.go (about) 1 package ct 2 3 import "fmt" 4 5 // LessOrEq returns 1 if x <= y and 0 otherwise. 6 // 7 // See golang.org/issues/42685. 8 func LessOrEq(x, y uint) uint { 9 x64 := uint64(x) 10 y64 := uint64(y) 11 12 gtb := x64 & ^y64 13 ltb := ^x64 & y64 14 15 ltb |= (ltb >> 1) 16 ltb |= (ltb >> 2) 17 ltb |= (ltb >> 4) 18 ltb |= (ltb >> 8) 19 ltb |= (ltb >> 16) 20 ltb |= (ltb >> 32) 21 22 bit := gtb &^ ltb 23 24 bit |= (bit >> 1) 25 bit |= (bit >> 2) 26 bit |= (bit >> 4) 27 bit |= (bit >> 8) 28 bit |= (bit >> 16) 29 bit |= (bit >> 32) 30 31 return uint(^bit & 1) 32 } 33 34 // Greater returns 1 if x > y and 0 otherwise. 35 // 36 // See golang.org/issues/42685. 37 func Greater(x, y uint64) uint64 { 38 gtb := x & ^y 39 ltb := ^x & y 40 41 ltb |= (ltb >> 1) 42 ltb |= (ltb >> 2) 43 ltb |= (ltb >> 4) 44 ltb |= (ltb >> 8) 45 ltb |= (ltb >> 16) 46 ltb |= (ltb >> 32) 47 48 bit := gtb &^ ltb 49 50 bit |= (bit >> 1) 51 bit |= (bit >> 2) 52 bit |= (bit >> 4) 53 bit |= (bit >> 8) 54 bit |= (bit >> 16) 55 bit |= (bit >> 32) 56 57 return bit & 1 58 } 59 60 // greater32 returns 1 if x > y and 0 otherwise. 61 // 62 // See golang.org/issues/42685. 63 func greater32(x, y uint32) uint32 { 64 gtb := x & ^y 65 ltb := ^x & y 66 67 ltb |= (ltb >> 1) 68 ltb |= (ltb >> 2) 69 ltb |= (ltb >> 4) 70 ltb |= (ltb >> 8) 71 ltb |= (ltb >> 16) 72 73 bit := gtb &^ ltb 74 75 bit |= (bit >> 1) 76 bit |= (bit >> 2) 77 bit |= (bit >> 4) 78 bit |= (bit >> 8) 79 bit |= (bit >> 16) 80 81 return bit & 1 82 } 83 84 func GreaterEq32(x, y uint32) uint32 { 85 return greater32(y, x) ^ 1 86 } 87 88 func GreaterEq64(x, y uint64) uint64 { 89 return Greater(y, x) ^ 1 90 } 91 92 // Equal64 returns 1 if x == y and 0 otherwise. 93 func Equal32(x, y uint32) uint32 { 94 return uint32((uint64(x^y) - 1) >> 63) 95 } 96 97 // Equal64 returns 1 if x == y and 0 otherwise. 98 func Equal64(x, y uint64) uint64 { 99 return (uint64(x^y) - 1) >> 63 100 } 101 102 // Select returns x if v == 1 and y if v == 0. 103 // 104 // The result is undefined if v is anything 105 // other than 1 or 0. 106 func Select32(v, x, y uint32) uint32 { 107 return ^(v-1)&x | (v-1)&y 108 } 109 110 // Select returns x if v == 1 and y if v == 0. 111 // 112 // The result is undefined if v is anything 113 // other than 1 or 0. 114 func Select64(v, x, y uint64) uint64 { 115 return ^(v-1)&x | (v-1)&y 116 } 117 118 // Div64 returns q = (hi, lo) / d and r = (hi, lo) % d. 119 func Div32(hi, lo, d uint32) (q, r uint32) { 120 ch := Equal32(hi, d) 121 hi = Select32(ch, 0, hi) 122 for k := 31; k > 0; k-- { 123 j := 32 - k 124 w := (hi << j) | (lo >> k) 125 ctl := GreaterEq32(w, d) | (hi >> k) 126 hi2 := (w - d) >> j 127 lo2 := lo - (d << k) 128 hi = Select32(ctl, hi2, hi) 129 lo = Select32(ctl, lo2, lo) 130 q |= ctl << k 131 } 132 cf := GreaterEq32(lo, d) | hi 133 q |= cf 134 r = Select32(cf, lo-d, lo) 135 return q, r 136 } 137 138 // Div64 returns q = (hi, lo) / d and r = (hi, lo) % d. 139 func Div64(hi, lo, d uint64) (q, r uint64) { 140 ch := Equal64(hi, d) 141 hi = Select64(ch, 0, hi) 142 for k := 63; k > 0; k-- { 143 j := 64 - k 144 w := (hi << j) | (lo >> k) 145 ctl := GreaterEq64(w, d) | (hi >> k) 146 hi2 := (w - d) >> j 147 lo2 := lo - (d << k) 148 fmt.Printf("lo=%d lo2=%d d=%d k=%d\n", lo, lo2, d, k) 149 hi = Select64(ctl, hi2, hi) 150 lo = Select64(ctl, lo2, lo) 151 q |= ctl << k 152 } 153 cf := GreaterEq64(lo, d) | hi 154 q |= cf 155 r = Select64(cf, lo-d, lo) 156 return q, r 157 }