Newsgroup: it.comp.lang.visual-basic
Titolo: Problemi nel calcolo del modulo di una divisione

Il modulo di una divisione si può calcolare con l'operatore Mod solo se il
numero è compreso nell' area di valità delle variabili Long, altrimenti si
verifica l'errore di run-time 6 Overflow.
In questi casi Microsoft suggerisce di calcolare il modulo con il seguente
codice :
Dim dblX as Double
Dim dblY as Double
dblX = 
2147483648
                ' numerator
dblY = 123                       ' denominator
' round off the numerator and denominator (ensure number is .0)
dblX = INT(dblX + .5)
dblY = INT(dblY + .5)
' Emulate integer division
MsgBox FIX(dblX / dblY)
' Emulate modulo arithmetic
MsgBox dblX - ( dblY * FIX(dblX / dblY) )
Neanche questo codice sembra però funzionare per numeri molto grandi es.
"423878493278493274897492742428" in quanto il valore risultante del modulo
risulta sempre zero.
Ringrazio in anticipo
flv-

Beh... puoi sempre fare così credo...
Chiaramente anche questo sistema ha dei limiti... ma moooolto ampi... :)
Diciamo che il limite é di circa 47 cifre binarie... (se non ricordo male)
Ovvero di una parte su 140 737 488 355 328
Dim Num as double
Dim Den as double
Dim Res as double
Dim Modu as double
res = int(num/den)
modu = num-den*res
Se non andasse bene...
Non ti resta che rispolverare quello che si insegna alle elementari... :)
Ovvero la "pappardella" divisoria... :)
1500 : 7 = 2
14
  1
Abbasso lo 0...
1500 : 7 = 21
14
  10
    7
    3
Abbasso lo 0...
1500 : 7 = 214
14
  10
    7
    30
    28
      2
Resto 2...
Quindi... con una bella routine ricorsiva...
Ho fatto un esempio... Non completamente testato... mettilo in un form... :)
Private Sub Form_Load()
    Dim resto As String
    MsgBox (Divisione("1500", "7", resto))
    MsgBox resto
    MsgBox (Divisione("11", "2", resto))
    MsgBox resto
    MsgBox (Divisione("11", "5", resto))
    MsgBox resto
    MsgBox (Divisione("150", "2", resto))
    MsgBox resto
    MsgBox (Divisione("11", "20", resto))
    MsgBox resto
    MsgBox (Divisione("11", "1", resto))
    MsgBox resto
End Sub
Public Function Divisione(ByVal Num As String, Den As String, resto As
String) As String   'Ho usato string perché sono insensibili ai limiti del
double...
    Dim DenLen As Long 'Lunghezza denominatore
    Dim NumTemp As String 'N° usate del numeratore per questo passaggio
    DenLen = Len(Den)
    If DenLen <= Len(Num) Then
      NumTemp = Left$(Num, DenLen)
      If Not EMaggioreUguale(NumTemp, Den) Then
        If DenLen < Len(Num) Then
          NumTemp = Left$(Num, DenLen + 1)
        Else
          resto = Num
          Exit Function
        End If
      End If
      Divisione = Dividi(NumTemp, Den, resto)
      Divisione = Divisione & Divisione(resto & Mid$(Num, Len(NumTemp) + 1),
Den, resto)
    Else
      resto = Num
    End If
End Function
Public Function EMaggioreUguale(Num1 As String, Num2 As String)
    If Len(Num1) > Len(Num2) Then 'Se non viene usata da altre funzioni
questo if lo si può eliminare e tenere solo la parte else
      EMaggioreUguale = True
    ElseIf Len(Num2) > Len(Num1) Then
      EMaggioreUguale = False
    Else
      Dim N As Long
      For N = 1 To Len(Num1)
        If Mid$(Num1, N, 1) > Mid$(Num2, N, 1) Then
          EMaggioreUguale = True
          Exit For
        ElseIf Mid$(Num1, N, 1) < Mid$(Num2, N, 1) Then
          EMaggioreUguale = False
          Exit For
        ElseIf Mid$(Num1, N, 1) = Mid$(Num2, N, 1) Then
          EMaggioreUguale = True
        End If
      Next N
    End If
End Function
Public Function Dividi(Num As String, Den As String, resto As String) As
String
    Dim Res As Long
    Res = 10
    Dim Prodotto As String
    Prodotto = Den & "0"
    Do While EMaggioreUguale(Prodotto, Num)
      Res = Res - 1
      Prodotto = MoltiplicaRidotto(Den, Res) 'Moltipica una stringa per un
numero... (non stringa-stringa, tanto qui verrà usata con massimo 9!
      If Prodotto = Num Then Exit Do
    Loop
    resto = Sottrai(Num, Prodotto)
    Dividi = Res
End Function
Public Function MoltiplicaRidotto(FattStr As String, FattNum As Long) As
String
    Dim Riporto As Long
    Dim Prodotto As Long
    Dim N As Long
    For N = 1 To Len(FattStr)
      Prodotto = Val(Mid$(FattStr, N, 1)) * FattNum + Riporto
      MoltiplicaRidotto = (Prodotto Mod 10) & MoltiplicaRidotto
      Riporto = Int(Prodotto / 10)
    Next N
    If Riporto > 0 Then
      MoltiplicaRidotto = Riporto & MoltiplicaRidotto
    Else
      Do While Left$(MoltiplicaRidotto, 1) = "0"
        MoltiplicaRidotto = Mid$(MoltiplicaRidotto, 2)
      Loop
    End If
End Function
Public Function Sottrai(Minuendo As String, Diminuendo As String) 'Come
cazz' si chiamava!
'Anche questa funzione non é prevista per numeri negativi!
    Dim Riporto As Long
    Dim Sott As Long
    Dim lenMin As Long
    Dim lenDim As Long
    lenMin = Len(Minuendo)
    lenDim = Len(Diminuendo)
    Dim N As Long
    For N = 0 To lenMin - 1
      If N < lenDim Then
        Sott = Val(Mid$(Minuendo, lenMin - N, 1)) - Riporto -
Val(Mid$(Diminuendo, lenDim - N, 1))
      Else
        If Riporto = 0 Then
          Sottrai = Left$(Minuendo, lenMin - N) & Sottrai
          Exit For
        End If
        Sott = Val(Mid$(Minuendo, lenMin - N, 1)) - Riporto
      End If
      If Sott < 0 Then
        Riporto = Int((-Sott) / 10)
        Sott = Sott + Riporto * 10
        If Sott < 0 Then
          Riporto = Riporto + 1
          Sott = Sott + 10
        End If
      End If
      Sottrai = Sott & Sottrai
    Next N
    Do While Left$(Sottrai, 1) = "0"
      Sottrai = Mid$(Sottrai, 2)
    Loop
End Function
P.S.= Nessuna pretesa che sia giusto... :)
P.S.2 = Si poteva fare più veloce... molto più veloce... ma non così
velocemente... nessuno mi uccida per questo!
P.S.3 = SOLO INTERI POSITIVI! Altrimenti apliatela voi... :(

 Beh... puoi sempre fare cosě credo...
.stracut.
Ma chi sei? Bravo! :-))))
______________________________________
 James Tiberius Kirk, matricola SC 937-076 CEC
   Nato a Riverside, nello Iowa, USA, Terra
             il 1277.1 (26/03/2233)

 ha scritto nel messaggio
news:Pqz27.4977$1u2.1...@news.infostrada.it...


> Ma chi sei? Bravo! :-))))
Grazie... :)
Mi godo gli applausi... ;)))
E' stato un piacere...
Ora il limite di precisione é spostato a 4 miliardi di cifre per numero! ;)
            Ciao
                    Allanon