LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Bitwise arrays

Root / Submissions / [.]

MZ952Created:
Variable = BTREAD(BinaryArray%, Index%, SeparationData$)
DEF BTARRY(ARRY, INDX%, _SEP$)
 DIM SEP$ = _SEP$
 DIM I%, TINDX%, SEP_MXI% = LEN(SEP$)-1
 INDX% = MAX(INDX%,.) 'Bounds checking.
 'Determines the start position of the "element" by summing the lengths of all those before it.
 FOR I%=.TO INDX%-1
  IF I%>SEP_MXI% THEN BREAK ENDIF
  INC TINDX%, ASC(SEP$[I%])-48
 NEXT I%
 'Bounds checking, in case the function is passed a bad SeparationData argument.
 IF INDX%>SEP_MXI% THEN
  INDX% = SEP_MXI%
  INC SEP$, CHR$(48+31-TINDX%)
 ENDIF
 'All the actual math.
 RETURN ARRY%>>TINDX% AND 2147483647>>31-(ASC(SEP$[INDX%])-48)
 'Works by taking the binary value &b01111111111111111111111111111111 and shifting it
 'rightward 31 units (the bitwise length of an integer minus the +/- flag) minus the length of the desired element.
 'For an element of length 3 (3 bits), the end result would look like this: &b00000000000000000000000000000111.
 'Next, it shifts the integer value storing the "array" over rightward the sum of all the lengths of the elements behind the desired one.
 'If our "array" looks like this: &b00000000000000010100000000000000 and the sum of all the elements' lengths behind our
 'desired element is 15, then the end result looks like this: &b00000000000000000000000000000101.
 'Lastly, the bits of the two values are ANDed, resulting in only the desired element's value. 
END
BinaryArray% is simply an integer storing the "array" data. Index% denotes the addressed index, starting from 0. SeparationData$ describes how the elements are separated. Each index of the string of SeparationData$ describes the length (number of bits) the corresponding index of the bitwise array uses. For example, S$ = "327A"; the first element will contain 3 bits, the second contains 2, the third contains 7, and the fourth contains 10—10, because "A" is the hexadecimal representation of the decimal value 10. This extends past hexadecimal, up to "U" which is 31. The first index of the string corresponds to the first index of the bitwise array, the second corresponds to the second, and so on. If you fail to specify the lengths of all the elements in the bitwise array, the function assumes that the remaining bits are one element. If you over-specify, your 3DS will delete itself.
DEF BTSET(ARRY%, INDX%, _SEP$, VAL%)
 'Just like to point out, this block all the way up to the three dashed lines is exactly the same as in that of the first function above.
 DIM SEP$ = _SEP$
 DIM I%, TINDX%, SEP_MXI% = LEN(SEP$)-1
 INDX% = MAX(INDX%,.)
 FOR I%=.TO INDX%-1
  IF I%>SEP_MXI% THEN BREAK ENDIF
  INC TINDX%, ASC(SEP$[I%])-48
 NEXT I%
 IF INDX%>SEP_MXI% THEN
  INDX% = SEP_MXI%
  INC SEP$, CHR$(48+31-TINDX%)
 ENDIF
 '---
 FOR I%=.TO ASC(SEP$[INDX%])-48-1
  IF ARRY% AND 1<<TINDX%+I% THEN DEC ARRY%, 1<<TINDX%+I% ENDIF
  INC ARRY%, (VAL% AND 1<<I% ||.)<<TINDX%+I%
 NEXT I%
 RETURN ARRY%
END
Can be used to set elements of a bitwise array. All the arguments have the same properties as the last. VAL% is just the value you're setting the particular element to be. Of course, make sure your value has no more than the right amount of bits for that element (specified by the element lengths in the SeparationData$ string). If you go over, those bits will be dropped. The length of a bitwise array (number of elements) is simply the length of its _SEP$. If you change the data associated with SEP$, the elements don't move themselves.
DEF BTRESET(ARRY%, _SEP0$, _SEP1$)
 DIM SEP0$ = _SEP0$, SEP1$ = _SEP1$
 DIM I%, MXI% = LEN(SEP0$)-1, ARRY0%
 FOR I%=.TO MXI%
  ARRY0% = BTSET(ARRY0%, I%, SEP1$, BTREAD(ARRY%, I%, SEP0$))
 NEXT I%
 RETURN ARRY0%
END
This will convert a bitwise array that had previously been defined by _SEP0$ and return a new one defined by _SEP1$. There it is I guess. 10 bucks says someone else already has a better version for this, especially for BTSET. Nothing clever there. It runs pretty fast actually, doing 1000 BTSET operations in an average 57 milliseconds, or about 0.057 milliseconds per call. Remember to like and subscribe if you want to see more videos like this one.

Why is this useful? It probably isn't. I'm not selling anything so