Split 8bit in 4bit

General FreeBASIC programming questions.
mrminecrafttnt
Posts: 133
Joined: Feb 11, 2013 12:23

Split 8bit in 4bit

Post by mrminecrafttnt »

How do i split and 8bit value in two 4 bit values in freebasic?
The theretical code exists but i dont know how to translate this in freebasic.. xD

Code: Select all


type ubyte4
    dim as ubyte hi : 4
    dim as ubyte lo : 4
    declare sub split(value as ubyte)
    declare function unsplit as ubyte
end type

sub ubyte4.split(value as ubyte)
   hi = (value & 0xF0)   
   lo = ((value<<4) & 0xF0)  
end sub



dim as ubyte value = &b11110101
dim as ubyte4 s
s.split(value)
print bin(s.hi)
print bin(s.lo)
sleep


UEZ
Posts: 1079
Joined: May 05, 2017 19:59
Location: Germany

Re: Split 8bit in 4bit

Post by UEZ »

Something like this here?

Code: Select all

Function Low4bit(n As Byte) As Byte
	Return n And &h0F
End Function

Function High4bit(n As Byte) As Byte
	Return (n And &hF0) Shr 4
End Function

Dim As Byte n = 165
'&hA5
'1010 0101
'10   5
'A    5
? "Hex: " & Hex(n)
?
? "High: " & Hex(High4bit(n))
? "Low: " & Hex(Low4bit(n))

Sleep
Last edited by UEZ on Nov 18, 2020 9:22, edited 1 time in total.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Split 8bit in 4bit

Post by jj2007 »

Keep it BASIC ;-)

Code: Select all

Dim shared As ubyte lo, hi

sub split(value as ubyte)
   lo = value and &HF
   hi = value shr 4
end sub

dim as ubyte value = &b11110101
split(value)
print bin(value)
print bin(hi);" ";bin(lo)
sleep
paul doe
Posts: 1878
Joined: Jul 25, 2017 17:22
Location: Argentina
Contact:

Re: Split 8bit in 4bit

Post by paul doe »

mrminecrafttnt wrote:...
The theretical code exists but i dont know how to translate this in freebasic.. xD
...
Almost verbatim, but with a union instead of a type (and the type inside containing the bit fields):

Code: Select all

union Nibbles
  as ubyte value
  
  type
    lo : 4 as ubyte
    hi : 4 as ubyte
  end type
end union

dim as Nibbles n = ( &b11110101 )

? bin( n.value, 8 )
? bin( n.hi, 4 )
? bin( n.lo, 4 )

sleep()
That's an interesting dialect. Which one is it?
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Split 8bit in 4bit

Post by fxm »

Advanced object structure issued from paul doe's structure:

Code: Select all

Type Byte8bitSplit
    Public:
        Declare Constructor (Byval b As Byte = 0)
        Declare Operator Let (Byval b As Byte)
        Declare Operator [] (Byval n As Integer) As Byte
    Private:
        Union
            Dim As Byte value
            Type
                Dim As Byte lo : 4
                Dim As Byte hi : 4
            End Type
        End Union
End Type

Constructor Byte8bitSplit (Byval b As Byte = 0)
    This.value = b
End Constructor

Operator Byte8bitSplit.Let (Byval b As Byte)
    This.value = b
End Operator

Operator Byte8bitSplit.[] (Byval n As Integer) As Byte
    Select Case As Const n
    Case 0  '' Byte 8bit
        Return This.value
    Case 1  '' Low  4bit
        Return This.lo
    Case 2  '' High 4bit
        Return This.hi
    End Select
    Return 0
End Operator

'------------------------------------------------------------

Dim As Byte8bitSplit b = &b10100101
Print "Byte 8bit: ";     Bin(b[0], 8)
Print "High 4bit: ";     Bin(b[2], 4)
Print "Low  4bit:     "; Bin(b[1], 4)
Print

b = &b01111110
Print "Byte 8bit: ";     Bin(b[0], 8)
Print "High 4bit: ";     Bin(b[2], 4)
Print "Low  4bit:     "; Bin(b[1], 4)
Print

Print "Byte 8bit: ";     Bin(Byte8bitSplit(&b01101101)[0], 8)
Print "High 4bit: ";     Bin(Byte8bitSplit(&b01101101)[2], 4)
Print "Low  4bit:     "; Bin(Byte8bitSplit(&b01101101)[1], 4)
Print

Sleep
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Split 8bit in 4bit

Post by dodicat »

Slap me down if I am wrong, but isn't 8 bit and 4 bit higher up the data type scale than byte?

Code: Select all



Function mkulongint(n1 As Ulong,n2 As Ulong) As Ulongint
    Dim As Ulongint res
    Cast(Ulong Ptr,@res)[0]=n1
    Cast(Ulong Ptr,@res)[1]=n2
    Return res
End Function

Sub getulongs(n As Ulongint, Byref L1 As Ulong,Byref L2 As Ulong)
    L1=Cast(Ulong Ptr,@n)[0]
    L2=Cast(Ulong Ptr,@n)[1]
End Sub


Dim As Ulong L1,L2
Dim As Ulongint u
do
Print
l1=rnd*4294967295
l2=rnd*4294967295
Print hex(l1),hex(l2),"two ulongs (4 bits each)"
u=mkulongint(l1,l2)
Print hex(u),"one ulongint (8 bits)"
l1=0
l2=0
getulongs(u,L1,L2)
Print hex(L1),hex(L2),"Return values from the ulongint :  two ulongs (4 bits each)"
print
print "Press any key or <escape> to finish"
Sleep 
loop until inkey=chr(27) 
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Split 8bit in 4bit

Post by fxm »

Are you confusing bit and byte deliberately in your code comment?
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Split 8bit in 4bit

Post by MrSwiss »

Proof of concept (of fxm's statement):

Code: Select all

' bits_and_bytes.bas -- (c) 2020-11-18, MrSwiss
'
' SizeOf() returns in: number of byte
'

Print "Variable", "Byte's", "bit's" : Print
Print "UByte size:    "; SizeOf(UByte),  SizeOf(UByte)  * 8
Print "UShort size:   "; SizeOf(UShort), SizeOf(UShort) * 8
Print "ULong size:    "; SizeOf(ULong),  SizeOf(ULong)  * 8
Print "ULongInt size: "; SizeOf(ULongInt), SizeOf(ULongInt) * 8
Print : Print
Print "... done ... ";
sleep
The question was IMO rethorical ...
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Split 8bit in 4bit

Post by dodicat »

It was the 4 bits that confused me, one byte is the smallest at 8 bits.
This is maybe better down that far.

Code: Select all


#define mk(a,b) a or b shl 8

dim as byte a,b
do
      a=rnd*128
      b=rnd*128
var m=mk(a,b)
print hex(m)
print hex(lobyte(m)),hex(hibyte(m))
print
print "Press any key or <escape> to finish"
sleep
loop until inkey=chr(27)  
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Split 8bit in 4bit

Post by MrSwiss »

@dodicat, your code deals with Bytes and Short (NOT byte split into Nibbles).
A Nibble is a 'half-Byte' (aka: 4 bits):

Code: Select all

' nibbles_and_bytes.bas -- (c) 2020-11-18, MrSwiss

Randomize
For i As UInteger = 0 To 999
    Rnd() : Rnd() : Rnd() : Rnd() : _
    Rnd() : Rnd() : Rnd() : Rnd()
Next

#Define mkUB(l, h)  (h) Shl 4 + (l)     ' construct UByte (from 2 nibbles)
#Define hiNib(v)    ((v) And &hF0) Shr 4' fetch hi-nibble (as UByte)
#Define loNib(v)    (v) And &h0F        ' fetch lo-nibble (dito)

Dim As UByte    a, b, m

Do
    a = Rnd() * 15                      ' hi-nibble
    b = Rnd() * 15                      ' lo-nibble
    m = mkUB(b, a)                      ' construct UByte
    Print Hex(m, 2)
    Print Hex(hiNib(m), 2), Hex(loNib(m), 2)
    Print
    Print "Press any key or [Ctrl] + [c] to finish"
    Sleep
Loop
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Split 8bit in 4bit

Post by jj2007 »

Amazing how much code can be produced for something as simple as that...

Code: Select all

dim as ubyte value = &b1010110
print bin(value)
print bin(value shr 4);" ";bin(value and &HF)
sleep
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Split 8bit in 4bit

Post by MrSwiss »

Simply to show, in how many different ways, one can obtain the same result.

The various methods have their strengths and weaknesses ... (once, few, multiple, many times).
caseih
Posts: 2198
Joined: Feb 26, 2007 5:32

Re: Split 8bit in 4bit

Post by caseih »

Sometimes letting a compiler do the bit masking is just easier than doing it manually. I remember implementing the FAT12 file system many years ago for a uni class. In the FAT12 file system, clusters were stored as a 12-bit field, meaning 3 bytes contained two clusters, which were stored as 2 12-bit fields, but the two clusters were stored together as a 3-byte, little-endian number for whatever reason. Whoever heard of using little endian to store a 3-byte long number? Bizarre choice, but one a compiler can deal with easily. Anyway picking the bits out manually is possible, but it's way easier to use a structure with bit fields.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Split 8bit in 4bit

Post by jj2007 »

caseih wrote:it's way easier to use a structure with bit fields.
How?

Code: Select all

dim as ubyte value = &b1010110
print bin(value)
print bin(value shr 4);" ";bin(value and &HF)		' simple, basic code (pun intended)

#define loNibble(x)  (x And 15)	' for those who like
#define hiNibble(x)  (x shr 4)	 ' it very complicated
print bin(hiNibble(value));" ";bin(loNibble(value))
sleep

Code: Select all

1010110
101 110
101 110
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Split 8bit in 4bit

Post by dodicat »

jj2007
The macros are tidier IMO

Code: Select all


#define loNibble(x)  (x And 15)             
#define hiNibble(x)  ((x And 240) shr 4)   
#define mk(a,b) a or b shl 4

dim as ubyte b,nh,nl
do
    b=rnd*255
    print "Hex number = "; hex(b),,"(number =";b;")"
    nh=hinibble(b)
    nl=lonibble(b)
    print "High ";hex(nh),"low ";hex(nl)
    print "Return hex:"
    print hex(mk(nl,nh))
    print
    print "Press any key or <escape> to finish"
    print
    sleep
    loop until inkey=chr(27)


 
The best solution is probably the union method,
Thanks MrSwiss for pointing out the stray ushort.
Post Reply