Android Question (SOLVED) An efficient way to calculate char parity

tigrot

Well-Known Member
Licensed User
Longtime User
Here is my last version code
B4X:
Sub parity(byt As Byte)As Int  ' Parity code(2=none, 0= even, 1=odd)
    If datalen=8 Then Return byt ' data lenght
    If paritytype=2 Then Return byt ' no parity
    Dim retbyt As Byte=byt
    Dim nbit As Int=0
    If byt>63 Then
        nbit=nbit+1
        byt=byt-64
    End If
    If byt>31 Then
        nbit=nbit+1
        byt=byt-32
    End If
    If byt>15 Then
        nbit=nbit+1
        byt=byt-16
    End If
    If byt>7 Then
        nbit=nbit+1
        byt=byt-8
    End If
    If byt>3 Then
        nbit=nbit+1
        byt=byt-4
    End If
    If byt>1 Then
        nbit=nbit+1
        byt=byt-2
    End If
    If byt=1 Then
        nbit=nbit+1
    End If
    If (nbit mod 2)> 0 Then
       If paritytype = 0 Then ' pari
         Return retbyt+128
       Else
         Return retbyt
       End If    
    Else
       If paritytype = 0 Then ' pari
         Return retbyt
       Else
         Return retbyt+128
       End If        
    End If

End Sub

Sub sendstring(testo() As Byte)as byte()
    Dim nc As Int
    Dim retchr As Int
    For nc = 0 To testo.Length-1
         retchr=parity(testo(nc))    
         If retchr<0 Then
             testo(nc)=256+retchr
         Else
             testo(nc)=retchr
        End If
    Next
   return testo
End Sub

this code solves a problem in case serial interface cannot use 7 bit datalength.(pls. tell interfaces' project managers that ISO is 7 bit, even parity)
I took away any complex calculation and so it works very well and fast as well.
Sendstring is the sub to call and it returns an array of byte, with correct parity. Datalen and paritytype are global variables. The values' meanings are on the sub's first line.
The most horrible piece of code I ever wrote in 44 years!
 
Last edited:
Upvote 0

Ed Brown

Active Member
Licensed User
Longtime User
I have not tested the performance of this ...

B4X:
nbit = nbit + Bit.And(Bit.UnsignedShiftRight(b, 0), 1)
nbit = nbit + Bit.And(Bit.UnsignedShiftRight(b, 1), 1)
nbit = nbit + Bit.And(Bit.UnsignedShiftRight(b, 2), 1)
nbit = nbit + Bit.And(Bit.UnsignedShiftRight(b, 3), 1)
nbit = nbit + Bit.And(Bit.UnsignedShiftRight(b, 4), 1)
nbit = nbit + Bit.And(Bit.UnsignedShiftRight(b, 5), 1)
nbit = nbit + Bit.And(Bit.UnsignedShiftRight(b, 6), 1)

If Bit.And(nbit, 1) Then
    If paritytype = 0 Then ' pari
        Return retbyt+128
    Else
        Return retbyt
    End If
Else
    If paritytype = 0 Then ' pari
        Return retbyt
    Else
        Return retbyt+128
    End If
End If

Looking at this...
B4X:
If byt>63 Then
 nbit=nbit+1
 byt=byt-64
End If

it will return true even for bit 7 and I am not sure if that is the desired result you were looking for?
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
I would just precalculate once a lookup table with the parity of any byte (even/odd). This will be the fastest option if using B4A.

The only thing to take into account is that if the byte is used as the index for the look-up table, it can be treated as negative if bit7=1. But if you only need to calculate parity for datalen=7, which means that the byte is <=127, there will be no need for this workaround

(not tested)
B4X:
Dim numberOfActiveBitsMod2(128) as Byte = Array as Byte(0,1,1,0,......) 'This table can be built for instance using your routine above

Sub FindParity( byt as Byte) as byte

    if datalen=8 then return byt
    if parityType=2 then return byt
    'If parity is even and we have an odd number of ones or parity is odd and we have an even number of ones
    if (numberOfActiveBitsMod2(byt)=1 and parityType=0) or (numberOfActiveBitsMod2(byt)=0 and parityType=1) Then '
        return byt+128
    else
        return byt
    end if
End Sub
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
Hi Ed(Ciao in Italy)
bit 7 is always off in Numeric Control since they use ASCII 7, or better it's substituted by parity bit. I've been struggling for 30 years in data transmissions and I have seen many horrible implementations!
Thank for your help!

Mauro
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
I would just precalculate once a lookup table with the parity of any byte (even/odd). This will be the fastest option if using B4A.

The only thing to take into account is that if the byte is used as the index for the look-up table, it can be treated as negative if bit7=1. But if you only need to calculate parity for datalen=7, which means that the byte is <=127, there will be no need for this workaround

(not tested)
B4X:
Dim numberOfActiveBitsMod2(128) as Byte = Array as Byte(0,1,1,0,......) 'This table can be built for instance using your routine above

Sub FindParity( byt as Byte) as byte

    if datalen=8 then return byt
    if parityType=2 then return byt
    'If parity is even and we have an odd number of ones or parity is odd and we have an even number of ones
    if (numberOfActiveBitsMod2(byt)=1 and parityType=0) or (numberOfActiveBitsMod2(byt)=0 and parityType=1) Then '
        return byt+128
    else
        return byt
    end if
End Sub

Nice Idea, Let me test the efficiency of the code against mine.
Thank for your kind help...

Ciao
Mauro
 
Upvote 0

Ed Brown

Active Member
Licensed User
Longtime User
I would just precalculate once a lookup table with the parity of any byte (even/odd). This will be the fastest option if using B4A.

The only thing to take into account is that if the byte is used as the index for the look-up table, it can be treated as negative if bit7=1. But if you only need to calculate parity for datalen=7, which means that the byte is <=127, there will be no need for this workaround

(not tested)
B4X:
Dim numberOfActiveBitsMod2(128) as Byte = Array as Byte(0,1,1,0,......) 'This table can be built for instance using your routine above

Sub FindParity( byt as Byte) as byte

    if datalen=8 then return byt
    if parityType=2 then return byt
    'If parity is even and we have an odd number of ones or parity is odd and we have an even number of ones
    if (numberOfActiveBitsMod2(byt)=1 and parityType=0) or (numberOfActiveBitsMod2(byt)=0 and parityType=1) Then '
        return byt+128
    else
        return byt
    end if
End Sub
This is a great idea and is going to be A LOT faster to determine the parity. Now why didn't I think of that..:rolleyes:
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
Better a couple of already calculated byte's arrays of 128 bytes each. The index is asc(char) the result is directly the value of the byte to send. One small program on a PC can do the trick. Every asc() has a corrispondent entry in two arrays, one for even, one for odd parity.
 
Upvote 0
Top