martedì 7 ottobre 2014

Arrotondamento dei turni teorici.

Ecco il piccolo codice che mi sono costruito per studiare le approssimazioni per difetto e per eccesso:
Sub main()
Dim cifraDouble As Double
Dim cifraInteger As Integer
cifraDouble = 1.4
cifraInteger = cifraDouble

Debug.Print ""
Debug.Print "Il valore della variabile Double è " & cifraDouble
Debug.Print "Valore della variabile double copiato in una variabile Integer " & cifraInteger
Debug.Print "Uso di Int " & Int(cifraDouble)
Debug.Print "Uso di CInt " & CInt(cifraDouble)
End Sub
Cambiando il valore di cifraDouble ottengo nella finestra immediata il valore ottenuto ponendo il valore in una variabile di tipo Integer o usando rispettivamente Int e CInt.
Il valore della variabile Double è 1,4
Valore della variabile double copiato in una variabile Integer 1
Uso di Int 1
Uso di CInt 1

Il valore della variabile Double è 1,5
Valore della variabile double copiato in una variabile Integer 2
Uso di Int 1
Uso di CInt 2

Il valore della variabile Double è 1,9
Valore della variabile double copiato in una variabile Integer 2
Uso di Int 1
Uso di CInt 2

Usare la variabile di tipo Integer o la parola chiave CInt ottiene gli stessi risultati, ossia arrotonda una cifra decimale fino a 0,5 di decimali all'intero inferiore, mentre la arrotonda se ha 0,5 o più di decimali all'intero superiore.
Invece Int arrotonda sempre per difetto, all'intero inferiore.
Per il mio programma sarà più conveniente usare CInt o porre il valore in una variabile di tipo Integer.


Resta il problema se c'è un numero uguale di elementi nei due gruppi.
Torno a considerare la cosa:
turni attribuiti card 17
turni attribuiti med 18
turni teorici card 18
turni teorici med 18
Ecco! Dal momento che ambedue le cifre in questo caso hanno 0.5 di decimali il numero viene arrotondato per eccesso in ambedue i turni, e si ha la "creazione" di un turno in più che non dovrebbe esserci.

Come risolvere la cosa?

La soluzione più giusta sarebbe risolvere la cosa a caso, togliendo casualmente un turno a uno dei due.
Dim turniTot As Integer
Dim medCar, medMed As Integer
Dim turniCar As Integer, turniMed As Integer
turniTot = k - 1 + f
medCar = 6
medMed = 6

turniCar = turniTot / (medCar + medMed) * medCar
turniMed = turniTot / (medCar + medMed) * medMed

If turniCar + turniMed > turniTot Then
    Dim estratto As Integer
    estratto = Int(Rnd() * 2)
    If estratto = 0 Then turniCar = turniCar - 1
    If estratto = 1 Then turniMed = turniMed - 1
End If
        
Debug.Print "turni teorici card " & turniCar
Debug.Print "turni teorici med " & turniMed
Così andiamo pure bene... ma diamo un'occhiata in diverse "estrazioni", nella finestra immediata, ai turni attribuiti e a quelli teorici ottenuti sottraendo a caso al numero falsamente gonfiato un turno:
turni attribuiti card 18
turni attribuiti med 17
turni teorici card 18
turni teorici med 17
turni attribuiti card 17
turni attribuiti med 18
turni teorici card 17
turni teorici med 18
turni attribuiti card 17
turni attribuiti med 18
turni teorici card 18
turni teorici med 17
...e mi rendo conto che una distribuzione "equa" era già stata fatta, in quanto il primo turno del mese era stato estratto casualmente mentre gli altri venivano in rigorosa alternanza.
Dunque non è il caso di andare avanti in elucubrazioni cervellotiche.
Basta fare che se il numero dei due gruppi è uguale non è necessario operare una correzione, e le cosa sono già sistemate da sé.

Nessun commento:

Posta un commento