github.com/tunabay/go-bitarray@v1.3.1/bitarray_compare.go (about) 1 // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved. 2 // Use of this source code is governed by the MIT license that can be found in 3 // the LICENSE file. 4 5 package bitarray 6 7 import ( 8 "bytes" 9 ) 10 11 // Compare returns an integer comparing two bit arrays lexicographically. The 12 // result will be 0 if x == y, -1 if x < y, and +1 if y < x. A nil argument is 13 // equivalent to an empty bit array. 14 func Compare(x, y BitArrayer) int { 15 var bax, bay *BitArray 16 if x != nil { 17 bax = x.BitArray() 18 } 19 if y != nil { 20 bay = y.BitArray() 21 } 22 xLen, yLen, xlty := bax.Len(), bay.Len(), -1 23 if yLen < xLen { 24 bax, bay, xLen, yLen, xlty = bay, bax, yLen, xLen, +1 25 } 26 27 switch { 28 case yLen == 0: 29 return 0 30 case xLen == 0: 31 return xlty 32 case bax.b == nil: 33 if xLen == yLen && (bay.b == nil || allBytesZero(bay.b)) { 34 return 0 35 } 36 return xlty 37 case bay.b == nil: 38 if allBytesZero(bax.b) { 39 if xLen == yLen { 40 return 0 41 } 42 return xlty 43 } 44 return -xlty 45 } 46 47 ce := bax.nBits >> 3 // end index of common bytes 48 cc := bytes.Compare(bax.b[:ce], bay.b[:ce]) 49 switch { 50 case 0 < cc: 51 return -xlty 52 case cc < 0: 53 return xlty 54 } 55 56 if bax.nBits&7 == 0 { // no more x bits 57 if xLen == yLen { 58 return 0 59 } 60 return xlty 61 } 62 63 // compare the fractional bits in the last byte 64 cs := 8 - bax.nBits&7 65 xl, yl := bax.b[ce]>>cs, bay.b[ce]>>cs 66 switch { 67 case yl < xl: 68 return -xlty 69 case xl < yl, xLen != yLen: 70 return xlty 71 } 72 73 return 0 74 } 75 76 // Equal returns whether the bit array is the same as specified one. 77 // nil and zero length bit array are considered to be equal. 78 func (ba *BitArray) Equal(x BitArrayer) bool { 79 var bax *BitArray 80 if x != nil { 81 bax = x.BitArray() 82 } 83 switch { 84 case ba.IsZero(): 85 return bax.IsZero() 86 case bax.IsZero(): 87 return false 88 case ba.nBits != bax.nBits: 89 return false 90 case ba.b == nil: 91 return bax.b == nil || allBytesZero(bax.b) 92 case bax.b == nil: 93 return allBytesZero(ba.b) 94 } 95 96 return bytes.Equal(ba.b, bax.b) 97 }