-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
04-03_arithmetic_bounds_propagating_logical.go
79 lines (75 loc) · 1.8 KB
/
04-03_arithmetic_bounds_propagating_logical.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package hd
// MinOR is min(x|y) for x in [minx, maxx] and y in [miny, maxy].
// This gives tighter bound than max(minx, miny).
func MinOR(minx, maxx, miny, maxy uint32) uint32 {
for m := uint32(0x8000_0000); m != 0; m >>= 1 {
if (^minx & miny & m) != 0 {
if temp := (minx | m) & -m; temp <= maxx {
minx = temp
break
}
} else {
if (minx & ^miny & m) != 0 {
if temp := (miny | m) & -m; temp <= maxy {
miny = temp
break
}
}
}
}
return minx | miny
}
// MaxOR is max(x|y) for x in [minx, maxx] and y in [miny, maxy].
// This gives tighter bound than maxx + maxy.
func MaxOR(minx, maxx, miny, maxy uint32) uint32 {
for m := uint32(0x8000_0000); m != 0; m >>= 1 {
if (maxx & maxy & m) != 0 {
if temp := (maxx - m) | (m - 1); temp >= minx {
maxx = temp
break
}
if temp := (maxy - m) | (m - 1); temp >= miny {
maxy = temp
break
}
}
}
return maxx | maxy
}
// MinAND is min(x&y) for x in [minx, maxx] and y in [miny, maxy].
// This gives tighter bound than 0.
func MinAND(minx, maxx, miny, maxy uint32) uint32 {
for m := uint32(0x8000_0000); m != 0; m >>= 1 {
if (^minx & ^miny & m) != 0 {
if temp := (minx | m) & -m; temp <= maxx {
minx = temp
break
}
if temp := (miny | m) & -m; temp <= maxy {
miny = temp
break
}
}
}
return minx & miny
}
// MaxAND is max(x|y) for x in [minx, maxx] and y in [miny, maxy].
// This gives tighter bound than min(maxx, maxy).
func MaxAND(minx, maxx, miny, maxy uint32) uint32 {
for m := uint32(0x8000_0000); m != 0; m >>= 1 {
if (maxx & ^maxy & m) != 0 {
if temp := (maxx & ^m) | (m - 1); temp >= minx {
maxx = temp
break
}
} else {
if (^maxx & maxy & m) != 0 {
if temp := (maxy & ^m) | (m - 1); temp >= miny {
maxy = temp
break
}
}
}
}
return maxx & maxy
}