Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11

Discussione: [VB6] Operatori logici

  1. #1
    Utente di HTML.it L'avatar di Mabi
    Registrato dal
    May 2002
    Messaggi
    1,245

    [VB6] Operatori logici

    In che modo posso compiere la semplice operazione:
    codice:
    (3793882082 And 255)
    Non riesco proprio a capire cosa possa essere il problema...

    Grazie
    ... e non usare while wend è una sintassi deprecata

  2. #2
    ma il tuo obiettivo qual'è?
    credo ke la and funzioni solo su valori booleani...

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    L'operatore AND non lavora solamente con i valori booleani ma con gli interi, realizzando l'operazione logica AND bit per bit.

    Ma i valori devono essere interi e quello indicato eccede il long, che e' l'intero piu' grande utilizzabile in VB.

    Dato che la AND e' fondamentalmente equivalente all'operazione modulo, anche se quest'ultimo e' anch'esso utilizzabile solamente con gli interi, si puo' ottenere con semplici operazioni. In particolare, per il valore indicato si ottiene con

    Print 3793882082-Int(3793882082/256)*256

    che equivale a

    Print 3793882082 And 255

  4. #4
    Utente di HTML.it L'avatar di Mabi
    Registrato dal
    May 2002
    Messaggi
    1,245
    oregon ti ringrazio per la risposta con cui sono riuscito a chiarirmi almeno in parte le idee.
    Infatti, consultando l'help non avevo molte indicazioni sui limiti della And (come tipologia di parametro avevo "Qualsiasi espressione").

    In questo caso posso sostituire la And con l'operazione da te indicata.
    Facendo così però riesco a risolvere solo temporaneamente.
    Se infatti dovessi affrontare altre operazioni del tipo (ad esempio usando l'operatore Mod) mi ritroverei con valori sempre fuori range.
    Il problema quindi è: come posso avere un valore sempre nel campo long (da 00000000 a FFFFFFFF)?
    Se infatti eccedo il limite, si genere un errore di Overflow.
    Io invece vorrei accaddesse una cosa del tipo:
    codice:
    Dim n1 As Long
    Dim n2 As Long
    
    n1 = &H87654321
    n2 = &H12345678
    
    n1 = n1 * n2
    '(n1 = &H70B88D78)
    Grazie
    ... e non usare while wend è una sintassi deprecata

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    C'e' qualcosa che non e' chiaro nella tua richiesta.

    Quando dici "nel campo long (da 00000000 a FFFFFFFF)" intendi nel campo unsigned long a 32 bit?

    Se e' cosi', in VB hai sicuramente delle difficolta' in quanto VB tratta i signed long a 32 bit.

    Pero' ci sono dei modi per gestire il problema. A questo punto l'operazione che hai proposto, se non ho capito male

    &H87654321 * &H12345678 = &H70B88D78

    mi lascia perplesso, dato che il risultato non e' corretto, ne' signed ne' unsigned ...

    A questo punto e' meglio che tu spieghi la faccenda ...

  6. #6
    Utente di HTML.it L'avatar di Mabi
    Registrato dal
    May 2002
    Messaggi
    1,245
    Io sapevo che il campo che va da 00000000 a FFFFFFFF è rappresentabile come hai detto tu con o senza segno.
    Quindi da 0 a 4294967295 senza segno; da 0 a +2147483647 e da 0 a -2147483647 con segno.

    Il problema è che voglio avere un valore sempre a 32 bit.
    Il risultato dell'operazione ovviamente eccede questo limite, infatti sarebbe: 693779765864729976 un valore che a 32 bit dovrebbe invece essere 1891143032 cioè 70B88D78.
    Ti dico che dovrebbe essere questo perchè provando con la semplice calcolatrice di windows, mi riesce a dare questo valore.
    Diciamo che vorrei ottenere un po' quello che accade in assembler con i registri a 32 bit, in cui ad esempio se io incremento il valore FFFFFFFF ottengo 0, senza l'Overflow che lo impedisce.
    ... e non usare while wend è una sintassi deprecata

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Allora ... ricapitoliamo

    L'intero piu' grande gestito da VB6 e' il Long che e' interpretato con la regola del complemento a 2 (quindi con segno).

    I suoi limiti sono -2147483648 ... +2147483647

    Ogni operazione che genera un overflow viene segnalato.

    Presumendo che tu non voglia (o possa) usare i floating point per quello che vuoi fare (un single o un double), in VB6 ti devi un po' "arrangiare" sapendo "esattamente" cosa vuoi fare ...

    Quindi, se tu vuoi gestire un AND, una moltiplicazione o una addizione con valori interi eccedenti i 32 bit, dovrai valutare 3 tipi di soluzioni diverse per i 3 diversi problemi ...

    Oppure implementare del codice assembler all'interno del codice VB per realizzare le operazioni con 32 e piu' bit senza overflow.

    A questo punto e' necessario capire "cosa" tu voglia fare in dettaglio ...

  8. #8
    Utente di HTML.it L'avatar di Mabi
    Registrato dal
    May 2002
    Messaggi
    1,245
    Originariamente inviato da oregon
    Presumendo che tu non voglia (o possa) usare i floating point per quello che vuoi fare (un single o un double), in VB6 ti devi un po' "arrangiare" sapendo "esattamente" cosa vuoi fare ...

    Quindi, se tu vuoi gestire un AND, una moltiplicazione o una addizione con valori interi eccedenti i 32 bit, dovrai valutare 3 tipi di soluzioni diverse per i 3 diversi problemi ...

    Oppure implementare del codice assembler all'interno del codice VB per realizzare le operazioni con 32 e piu' bit senza overflow.

    A questo punto e' necessario capire "cosa" tu voglia fare in dettaglio ...
    Allora, non posso usare i floating point perchè assegnando il risultato ad una variabile di questo tipo diventa impreciso riottenerne il valore a 32 bit e si rischia sempre l'overflow.

    Penso che come hai detto tu è necessario valutare la soluzione appropriata.
    Siccome l'AND ed altri operatori logici funzionano con valori al massimo di 32 bit, la soluzione è risolvere il prodotto a 64 bit così da avere i 32 superiori e i 32 inferiori.
    Per la somma infatti, il problema del'overflow non si presenta.

    Cosa intendi con implementare codice assembler ?
    Io so che non è possibile includerne in VB.
    ... e non usare while wend è una sintassi deprecata

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da Mabi
    Cosa intendi con implementare codice assembler ?
    Io so che non è possibile includerne in VB.
    E chi te lo ha detto? E' possibilissimo invece ...

    Ad esempio, partiamo dalla tua moltiplicazione del cui risultato vuoi la parte a 32 bit meno significativa ...

    Parlo dell'operazione

    &H87654321 * &H12345678

    e della parte di risultato che ti interessa : &H70B88D78

    Questo il codice che ho scritto per tale operazione

    codice:
    Private Declare Function CallWindowProc Lib "user32" _
    Alias "CallWindowProcA" (ByVal pLShiftCode As Long, _
                            ByRef p1 As Long, _
                            ByVal p2 As Long, _
                            ByVal p3 As Long, _
                            ByVal p4 As Long) As Long
    
    Dim MulCode() As Byte
    Dim pMul As Long
    
    Private Sub Form_Load()
      ReDim MulCode(0 To 22)
        
      MulCode(0)  = &H55  ' push ebp
      MulCode(1)  = &H8B  ' mov ebp, esp
      MulCode(2)  = &HEC  
      MulCode(3)  = &H57  ' push edi
      MulCode(4)  = &H8B  ' mov edi, [ebp+8]
      MulCode(5)  = &H7D
      MulCode(6)  = &H08
      MulCode(7)  = &H8B  ' mov ecx, [ebp+12]
      MulCode(8)  = &H4D
      MulCode(9)  = &H0C
      MulCode(10) = &H8B  ' mov eax, [edi]
      MulCode(11) = &H07
      MulCode(12) = &HF7  ' mul ecx
      MulCode(13) = &HE1
      MulCode(14) = &H89  ' mov [edi], eax
      MulCode(15) = &H07
      MulCode(16) = &H5F  ' pop edi
      MulCode(17) = &H8B  ' mov esp, ebp
      MulCode(18) = &HE5
      MulCode(19) = &H5D  ' pop ebp
      MulCode(20) = &HC2  ' ret 16
      MulCode(21) = &H10
      MulCode(22) = &H00
        
      pMul = VarPtr(MulCode(0))
    End Sub
    
    Private Sub Command1_Click()
      Dim VA As Long
      Dim VB As Long
        
      VA = &H12345678  ' Primo valore
      VB = &H87654321  ' Secondo valore
        
      CallWindowProc pMul, VA, VB, 0, 0
    
      Print Hex$(VA)   ' Risultato in VA
    End Sub
    Fammi sapere

  10. #10
    Utente di HTML.it L'avatar di Mabi
    Registrato dal
    May 2002
    Messaggi
    1,245
    Ciao oregon

    Scusami per il ritardo nel rispondere.
    Il tuo codice è assolutamente ottimo ed è per me un riferimento in quanto ne ero a conoscenza soltanto in minima parte.

    Ho provato però a cercare una soluzione alternativa utilizzando quello che c'è in VB e sono a riuscito ad ottentere lo stesso risultato.
    Praticamente considero i termini dell'operazione come array di byte e ne eseguo la moltiplicazione trasportando il risultato ancora in un array di byte.
    Successivamente riconverto il risultato in un long con segno.

    Ad esempio:
    codice:
    Private Sub Command1_Click()
    Dim Numero1(3) As Byte
    Dim Numero2(3) As Byte
    Dim Risultato() As Byte
    Dim RisLong As Long
    
    
    '&H87654321
    Numero1(3) = &H87
    Numero1(2) = &H65
    Numero1(1) = &H43
    Numero1(0) = &H21
    '&H12345678
    Numero2(3) = &H12
    Numero2(2) = &H34
    Numero2(1) = &H56
    Numero2(0) = &H78
    Call Moltiplicazione(Numero1, Numero2, Risultato)
    Call BytesInLong(Risultato, RisLong)
    
    '&H70B88D78
    MsgBox Hex(RisLong)
    
    End Sub
    
    
    Private Sub Moltiplicazione(ByRef Moltiplicando() As Byte, ByRef Moltiplicatore() As Byte, ByRef Prodotto() As Byte)
    On Error Resume Next
    
    Dim Cont1 As Integer
    Dim Cont2 As Integer
    Dim ContRiporto As Integer
    
    Dim a As Long
    Dim b As Long
    Dim c As Long
    Dim d As Long
    
    ReDim Prodotto(0)
    
    
    'Elimina eventuali byte vuoti
    'ad es. 0000AABB = AABB
    '------------------------------------
    Cont1 = UBound(Moltiplicando)
    Do While (a = 0&) And (Cont1 > 0)
      a = CLng(Moltiplicando(Cont1))
      If (a = 0&) Then
        ReDim Preserve Moltiplicando(Cont1 - 1)
      End If
      Cont1 = (Cont1 - 1)
    Loop
    
    Cont1 = UBound(Moltiplicatore)
    a = 0&
    Do While (a = 0&) And (Cont1 > 0)
      a = CLng(Moltiplicatore(Cont1))
      If (a = 0&) Then
        ReDim Preserve Moltiplicatore(Cont1 - 1)
      End If
      Cont1 = (Cont1 - 1)
    Loop
    '------------------------------------
    
    
    For Cont1 = 0 To UBound(Moltiplicando)
    
      a = CLng(Moltiplicando(Cont1))
      
      For Cont2 = 0 To UBound(Moltiplicatore)
      
        b = CLng(Moltiplicatore(Cont2))
        d = a * b
        
        If d > 0 Then
        
          '---------------------------------------------
          ' PRIMO BYTE DEL PRODOTTO
          '---------------------------------------------
          If (Cont1 + Cont2) > UBound(Prodotto) Then
            ReDim Preserve Prodotto(Cont1 + Cont2)
          End If
        
          c = Prodotto(Cont1 + Cont2)
          c = c + (d And 255&)
          Prodotto(Cont1 + Cont2) = CByte((c And 255&))
        
            ' Gestione riporto
            c = c \ 256&
            ContRiporto = Cont2
            Do While (c > 0&)
              If (Cont1 + ContRiporto + 1) > UBound(Prodotto) Then
                ReDim Preserve Prodotto(Cont1 + ContRiporto + 1)
              End If
            
              c = c + CLng(Prodotto(Cont1 + ContRiporto + 1))
              Prodotto(Cont1 + ContRiporto + 1) = CByte((c And 255&))
          
              ContRiporto = ContRiporto + 1
              c = c \ 256&
            Loop
    
        
          d = d \ 256&
          If d > 0 Then
          
            '---------------------------------------------
            ' SECONDO BYTE DEL PRODOTTO
            '---------------------------------------------
            If (Cont1 + Cont2 + 1) > UBound(Prodotto) Then
              ReDim Preserve Prodotto(Cont1 + Cont2 + 1)
            End If
        
            c = CLng(Prodotto(Cont1 + Cont2 + 1))
            c = c + (d And 255&)
            Prodotto(Cont1 + Cont2 + 1) = CByte((c And 255&))
        
              ' Gestione riporto
              c = c \ 256&
              ContRiporto = Cont2
              Do While (c > 0&)
                If (Cont1 + ContRiporto + 2) > UBound(Prodotto) Then
                  ReDim Preserve Prodotto(Cont1 + ContRiporto + 2)
                End If
    
                c = c + CLng(Prodotto(Cont1 + ContRiporto + 2))
                Prodotto(Cont1 + ContRiporto + 2) = CByte((c And 255&))
          
                ContRiporto = ContRiporto + 1
                c = c \ 256&
              Loop
            
          End If
        End If
    
      Next Cont2
    Next Cont1
    
    End Sub
    
    Private Sub BytesInLong(ByRef ArrByte() As Byte, ByRef Var As Long)
    On Error Resume Next
    
    Dim Cont As Integer
    Dim Num As Integer
    Dim Massimo As Integer
    
    
    Massimo = UBound(ArrByte)
    If UBound(ArrByte) > 3 Then
      Massimo = 3
    End If
    
    If Massimo < 3 Then
      Var = 0
      For Cont = 0 To Massimo
        Var = Var + (ArrByte(Cont) * (256 ^ Cont))
      Next Cont
      
    Else
    
      If ArrByte(3) < 128 Then
        Var = 0
        For Cont = 0 To Massimo
          Var = Var + (ArrByte(Cont) * (256 ^ Cont))
        Next Cont
      Else
        Var = 0
        For Cont = 0 To Massimo
          If Cont = 0 Then
            Num = 256 - ArrByte(Cont)
          Else
            Num = 255 - ArrByte(Cont)
          End If
          
          Var = Var + (Num * (256 ^ Cont))
        Next Cont
        
        Var = Var * -1
      End If
      
    End If
    
    End Sub
    Di sicuro è meglio utilizzare la tua soluzione, però mi sono divertito a provare.

    Grazie
    ... e non usare while wend è una sintassi deprecata

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.