Accessing Bits

BlitzMax Forums/BlitzMax Programming/Accessing Bits

Drey(Posted 2006) [#1]
I would like to learn how to break a byte down to it's bit level. So i can access that one bit to settings. Similar to the Constant techinques found in openGL and Max2D collision system.

00000001 = 1
00000010 = 2
00000100 = 4

I can add these values together

00000111 = 7

Those numbers never need to "carry" so i can use 8 boolean switches for settings.

I remember looking up the math for it before. Kinda forget it though. I want to go to bed so..can you help me. Thanks for you time :D.


Perturbatio(Posted 2006) [#2]
you can use bitwise and ( & )

Print 7 & %00000010


Function bitIsSet(bit:Int , value:Int)
	mask:String = ""
	For Local i:Int = 8 To 1 Step -1
		If i = bit Then 
			mask:+ "1"
		Else 
			mask:+ "0"
		EndIf
	Next
	
	If mask.toInt() & value Then Return True Else Return False
End Function

For Local i:Int = 1 To 8
	Print bitset(i, 7)
Next



Defoc8(Posted 2006) [#3]
128 64 32 16 8 4 2 1
$FF = 1 1 1 1 1 1 1 1
$0F = 0 0 0 0 1 1 1 1
$01 = 0 0 0 0 0 0 0 1 - refreshing your memory?

test if bit zero is set..
if(mask & $01)do something..

test if bit 15 is set
if(mask & $80)do something

mask out most sig nibble
mask=mask & $0F


ImaginaryHuman(Posted 2006) [#4]
To isolate only one bit (or a set of bits) and exclude all the rest, AND a mask with the value. What you have left is only the bits you asked for.

Also if you don't know what bit you're looking for, put $1 into a variable, then use:

Local a:Int=$1 Shl BitNumber

to move that bit into the bit that you want (numbered from 0). Then that gives you the mask with which you can isolate the bit in whatever value you have. Then you can do:

Value=(Value & ($1 Shl BitNumber)) Shr BitNumber

if you want to put that bit right justified in the variable, so you can do math on it


Drey(Posted 2006) [#5]
yeah, i figured it out laying in bed before i went to sleep last night. Thanks for all your help..i luv you guys! haha


Tachyon(Posted 2006) [#6]
Pert:
I was testing out your code above. If I change the line:
Print bitisset(i, 7)
to
Print bitisset(i, 8)
the output is:
0
1
0
1
0
0
0
0
Which is binary "10", not "8". What gives?


Perturbatio(Posted 2006) [#7]
what gives is that I've probably messed up somewhere. I blame it on lack of sleep.


Chris C(Posted 2006) [#8]
theres some oddness with powers and floats heres what I had to do to get it to work....

SuperStrict

Function bitIsSet:Int(bit:Int , value:Int)
	Local mask:Int = 0
	For Local i:Int = 0 To 15
		If i = bit Then mask:+ Int((2^i)+0.1)
'		Print Int((2^i)+0.1)
	Next
'Print "mask="+mask	
	If mask & value Then Return True Else Return False
End Function

For Local i:Int = 0 To 7
	Print bitisset(i, 10)
Next



Yan(Posted 2006) [#9]
SuperStrict

Local flag%

SetBit(flag, 7)
Print Bin(flag)
Print CheckBit(flag, 7)
Print 
ClearBit(flag, 7)
Print Bin(flag)
Print CheckBit(flag, 7)
Print 
ToggleBit(flag, 7)
Print Bin(flag)
Print CheckBit(flag, 7)

End


Function CheckBit%(value%, bit%)
  Return (value & (1 Shl bit)) Shr bit
End Function

Function SetBit%(value% Var, bit%)
  value :| (1 Shl bit)
End Function

Function ClearBit%(value% Var, bit%)
  value :& ~(1 Shl bit)
End Function

Function ToggleBit%(value% Var, bit%)  
  value :~ (1 Shl bit)
End Function



Tachyon(Posted 2006) [#10]
Ian: nice.


VP(Posted 2006) [#11]
The Blitz3D code for my bitmap font thingy (see sig) uses bitflags in a fairly programmer-friendly manner. I left the values as binary rather than obfuscate (slightly, I know) to hex.

This is the way things were done on the Amiga ;) Probably slightly redundant now, but I still like it.