XOR vs UINT16   otázka

VB.NET

Prosil by som o radu, ako spraviť operáciu XOR medzi dvomi UINT16 premennými.

Ďakujem.

(VB .NET 2003)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Že by pomocí operátoru Xor?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Áno predstavte si, že to ma tiež napadlo ;-). Teraz som to skúšal na vb 2008. Ide všetko v poriadku. Zvláda dokonca xor aj medzi uint16 a integer. Ale vo VB 2003 mi to nechce spraviť xor medzi ničím iným iba medzi integer.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Podle MSDN (http://msdn.microsoft.com/en-us/library/... je jediným omezením u Xor operátoru ve VB 7.1 to, že obě hodnoty musejí být stejného typu. Jakou to hlásí vyjímku, případně chybu při kompilaci?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Buď obě proměnné přetypujte přes CInt na Integer, proveďte xor tam, a přetypujte zpátky, nebo bude možná xor fungovat i na obskurním typu UInt16. Existuje nějaký rozumný důvod, proč používat tento šílený datový typ? Zabere sice o 2 bajty méně, ale ve spoustě případů je možná lepší sežrat více paměti a ušetřit si problémy. Záleží ovšem, kolik hodnot uchováváte, pokud jsou jich řádově desítky milionů, už to smysl má.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dátový typ UInt16 som použil preto, lebo som prepisoval funkciu pre CheckSum priamo od výrobcu zariadenia. Prepisoval som ju zo starého Cčka.

Private Function CalcCrc(ByVal crcSum As System.UInt16, ByVal dataChar As Byte) As System.UInt16
        Dim myCrcSum As Integer = Integer.Parse(crcSum.ToString)
        myCrcsum = myCrcsum Xor dataChar * 256
        For i As Integer = 0 To 7
            If myCrcSum > &H7FFF Then
                myCrcSum = (myCrcSum * 2) Xor &H8005
            Else
                myCrcSum *= 2
            End If
        Next
        If myCrcSum < 2 ^ 16 Then
            Return System.UInt16.Parse(crcSum.ToString)
        Else
            Throw New OverflowException("crcSum je príliš velké aby mohlo byt skonvertované na UInt16")
        End If
    End Function

Všetko vypadá, že funguje správne ibaže, keď príde do datachar číslo 1 a v cykle i nadobudne hodnotu 7 vtedy myCrcSum je väčšie ako 32767(&H7FFF) a výsledkom riadku myCrcSum = (myCrcSum * 2) Xor &H8005 je potom 98309 čo je väčšie ako 2 na 16 a teda sa to nedá na UInt16 previesť. Ja to dávam za chybu tomu, že sa xor počíta medzi integermi a nie medzi uint16.

Toto je starší kód od výrobcu zariadenia pre Checksum

unsigned int calcCrc(unsigned int crcSum, unsigned char datachar)

{

unsigned char count;

crcSum = crcSum ^ (datachar * 256);

for (count = 0;count <=7;count++)

{

if (crcSum > 0x7FFF)

crcSum = (crcSum * 2) ^ 0x8005;

else

crcSum = crcSum * 2;

}

return crcSum;

}

Dátové typy od výrobcu :

char - 1 byte unsigned integer, value 0-255

unsigned int - 2 byte unsigned integer, value 0 - 65.535

Problém je, že VB .NET 2003 nedokáže urobiť štandardne XOR medzi dátovými typmi UINT16

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Mimochodem pro UInt16 se používá název UShort. Všechny datové typy platformy .NET mají svůj název v daném jazyce.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

UShort asi vo vb .net 2003 ešte neexistoval. Resp. niečo také sa vo vb .net 2003 nedá použiť.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

A na UIntu to nepůjde?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Bohužiaľ ani dátový typ UINTEGER(s takýmto názvom) ešte 2003 nepodporuje. S UInt32 XOR tak isto nefunguje. Začínam mať obavu, že sa to nedá nejak jednoducho v 2003 napísať a budem si musieť spraviť xor ručne po bitoch.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak som napísal triedu, ktorá ručne počíta XOR pre dátový typ UInt16. Nie je to pekne napísané a dokonca to ani nerieši môj problém. Chyba je zrejmne niekde inde.

Kód zverejňujem, možno sa niekomu zíde.

Friend Class UInt16Xor
    Public Function DoXor(ByVal number1 As UInt16, ByVal number2 As UInt16) As UInt16
        Dim resoult1, resoult2, xorValue As String
        Dim intResoult As Integer
        To2Base(System.Convert.ToInt32(number1), resoult1)
        To2Base(System.Convert.ToInt32(number2), resoult2)
        xorValue = MyXor(resoult1, resoult2)
        intResoult = To10Base(xorValue)
        Return System.Convert.ToUInt16(intResoult)
    End Function
    Private Sub To2Base(ByVal number As Integer, ByRef resoult As String)
        resoult &= CStr(number Mod 2)
        number \= 2
        If number > 1 Then
            To2Base(number, resoult)
        Else
            resoult &= CStr(number)
            For i As Integer = resoult.Length To 15
                resoult &= "0"
            Next
            resoult = Reverse(resoult)
        End If
    End Sub
    Private Function To10Base(ByVal number As String) As Integer
        Dim resoult As Integer
        For i As Integer = 15 To 0 Step -1
            If number.Chars(i) = "1" Then resoult += CInt(2 ^ (15 - i))
        Next
        Return resoult
    End Function
    Private Function Reverse(ByVal value As String) As String
        If value.Length > 1 Then
            Dim workingValue As New System.Text.StringBuilder
            For position As Int32 = value.Length - 1 To 0 Step -1
                workingValue.Append(value.Chars(position))
            Next
            Return workingValue.ToString
        Else
            Return value
        End If
    End Function
    Private Function MyXor(ByVal firstBits As String, ByVal secondBits As String) As String
        Dim resoult As String
        For i As Integer = 0 To 15
            If firstBits.Chars(i) = "0" And secondBits.Chars(i) = "0" Then resoult &= "0"
            If firstBits.Chars(i) = "0" And secondBits.Chars(i) = "1" Then resoult &= "1"
            If firstBits.Chars(i) = "1" And secondBits.Chars(i) = "0" Then resoult &= "1"
            If firstBits.Chars(i) = "1" And secondBits.Chars(i) = "1" Then resoult &= "0"
        Next
        Return resoult
    End Function
End Class

Trieda sa potom používa napr. takto :

 Dim access As New UInt16Xor
        Dim UInt16Number As UInt16 = access.DoXor(System.Convert.ToUInt16(0), System.Convert.ToUInt16(256))

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback