Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: bitset help

From: greggirwin:mindspring at: 26-Sep-2002 12:26

Hi Romano, << I do not understand how can be used all this new stuff from the new betas. Can someone make an useful example to me? I knows only how to use bitset in parse rule for char, but this seems something different. >> Bitsets can be very handy if you have a really large number of boolean flags to keep track of and want to use minimal space and processing power (in general). The idea, of course, is that each flag only takes one bit, which means you can store boatloads of them in little memory when compared to, say, a normal boolean/logic! value that probably uses 32 bits (or more in the future :). Here is something I just hacked together very quickly (really, truly, very little testing, probably lots of problems, you have been warned, watch for wrap, requires latest betas...I think, blah blah blah). --Gregg REBOL [ Title: "Bit Tools" Author: "Gregg Irwin" EMail: [greggirwin--acm--org] File: %bit-tools.r ] bit: make object! [ ; Quick hack! No real thought about naming issues. May be jumping ; through a lot of unnecessary hoops, but some things that I ; thought should work didn't. :\ ; Could/should CLEAR change bitset in place? ; Should bit indexes be treated as 0 based or 1 based? ; Note XOR naming issue in comment. ; Add TOGGLE function to flip bits? ; Some functions could easily take blocks to check the status of ; multiple bits (e.g. SET?). ; This is a special version just for this purpose, and always rounds up. ; So, why pass in the interval parameter? Good question. :) round-to-interval: func [value interval /local whole-val diff] [ whole-val: to integer! value / interval diff: either 0 = remainder value interval [0][1] whole-val + diff * interval ] bitset-from-bits: func [ bits [integer! block!] "Bit indices." /local result ][ bits: compose [(bits)] result: make bitset! round-to-interval max 1 first maximum-of bits 8 foreach bit bits [insert result bit] ] and: func [set1 [bitset!] set2 [bitset!]] [ intersect set1 set2 ] or: func [set1 [bitset!] set2 [bitset!]] [ union set1 set2 ] ; Just using to binary! on bitsets doesn't work. You get junk ; at the end if the bitset is short than 256 bits. ; This is called BXOR because calling it XOR and then referencing ; the standard XOR function as SYSTEM/WORDS/XOR fails. Must be ; missing something obvious, but I'm not seeing it. Need more coffee. ; There has *got* to be a better way than this! bxor: func [set1 [bitset!] set2 [bitset!] /local b1 b2] [ (head system/words/clear at to binary! set1 add 1 divide length? set1 8) xor (head system/words/clear at to binary! set2 add 1 divide length? set2 8) ] not: func [bitset [bitset!]] [ complement bitset ] get: func [ bitset [bitset!] index [integer!] "Which bit (0 to (length? value) - 1)" ][ either empty? and bitset bitset-from-bits index [0][1] ] set: func [ bitset [bitset!] index [integer!] "Which bit (0 to (length? value) - 1)" ][ insert bitset index ] set?: func [ bitset [bitset!] index [integer!] "Which bit (0 to (length? value) - 1)" ][ either empty? and bitset bitset-from-bits index [false][true] ] clear: func [ bitset [bitset!] index [integer!] "Which bit (0 to (length? value) - 1)" ][ and bitset complement bitset-from-bits index ] ] ; Paste this into the console to see the results in the conext of calls. print items: make bitset! 40 print bit/set items 0 print bit/set items 39 print bit/set? items 0 print bit/set? items 1 print bit/set? items 38 print bit/set? items 39 print bit/get items 0 print bit/get items 1 print bit/get items 38 print bit/get items 39 print items2: complement items print bit/and items items2 print bit/or items items2 print bit/bxor items items2 print items: bit/clear items 0 print items: bit/clear items 39 halt