View Full Version : [DOS-BATCH] Matematica su Interi grandi
einstein1969
11-05-2011, 21:23
Salve a tutti,
non so se qui si estende anche all'interprete dos batch (nt/xp).
Devo fare una procedura che ritorna lo spazio libero su disco e poi dividere il risultato per 1024 (o 1024*1024)
Solo che l'interprete arriva a gestire gli interi fino a 32 bit.
Non vorrei usare utility di terze parti se possibile.
Qualcuno mi puo' aiutare a trovare una soluzione?
Grazie
einstein1969
12-05-2011, 22:51
Ho provato con la divisione e mi sono reso conto che potevo usare una proprietà dei numeri decimali.
Es. 1234567890/123456 = 1234567890/100000 - Errore
Poi ho calcolato l'errore commesso.
Ho visto che N/M si puo' anche scrivere in N/(A+B)
Poi ho posto N/(A+B) = N/A - Errore
da cui Errore = B*N/(A*(A+B))
La cosa poteva andare ma non e' semplice da realizzare.
Ho poi trovato l'algoritmo di Karatsuba (http://it.wikipedia.org/wiki/Algoritmo_di_Karatsuba) che ricorda un po' quello che ho fatto. Ma ce ne sono anche altri (algorithmhttp://it.wikipedia.org/wiki/Moltiplicazione_Toom-Cook)... più veloci (http://en.wikipedia.org/wiki/Sch%C3%B6nhage-Strassen_).
Solo che dovrei fare una moltiplicazione per l'inverso di un numero.
In java l'ho trovato (http://icodesnippet.com/snippet/java/multiplication-of-large-numbers-multiplicacion-de-numeros-grandes)
Qualcuno che mi da una mano a capire il codice in java?
.
Proviamo.. Hai già il codice?
Mmm non so se con VBScript (http://msdn.microsoft.com/en-us/library/t0aew7h6%28v=vs.85%29.aspx) le cose ti vengano più semplici...
banryu79
13-05-2011, 10:36
@einstein1969: ciao, l'algoritmo di Karatsuba, di cui hai postato link a una implementazione in Java, non penso che risolva il tuo problema (o almeno io non ho capito come) dato che la sua utilità è data dal fatto che ha una complessità asintotica migliore di quella dell'algoritmo naive per moltiplicare gli interi, però val la pena usarlo quando gli interi in questione sono davvero molto molto grandi (nel sorgente linkato hanno posto un valore di soglia di 1000 cifre binarie).
In ogni caso resta il problema di rappresentarli questi interi molto grandi, problema che nel codice Java da te linkato viene risolto utilizzando la classe java.math.BigInteger, un tipo che rappresenta interi di grandezza arbitraria.
Io opterei per VBScript, come consigliato da WarDuck!
einstein1969
13-05-2011, 12:40
GRazie ragazzi ,
veramente tutti gentili.
@ndakota
Il codice e' nel mio secondo post, e' in java.
@WarDuck
Grazie del link. Mi sa che dovro' ripiegare al vbscript. Non lo conosco affatto. Sai se e' disponibile su tutte le piattaforme MS windows (da xp in poi) ? Va installato?
@banryu79
Immaginavo che sarebbe stato un bagno di sangue.
Comunque per esempio con il mio metodo sono riuscito a fare una procedura "statica" per la divisione per (1024*1024*1024)
Cioè il passaggio da byte a Giga bytes
es.
rem setto il valore grande (circa 2 Tera)
set gb=2100700123456
rem Rimuovo la parte poco significativa (mi servono solo 3 decimali dopo la virgola)
set gb=%gb:~0,-6%
rem applico la formula:N/(A+B)=N/A-[B*N/(A*(A+B))] con A =1,10,100,1000,
rem 10000,100000,etc cosi la divisione e' uno shift decimale che si puo' fare
rem anche senza dividere ma con operazioni su stringhe.
rem Uso la formula per due livelli (dovrebbero bastare per tre decimali dopo
rem la virgola.
rem primo livello:
rem N/M=2100700123456/(1024*1024*1024)=2100700123456/1073741824=
rem =2100700123456/(1000000000+73741824)=
rem =2100700123456/1000000000-[73741824*2100700123456/(1000000000*(1000000000+73741824))]
rem Per il secondo procedo in modo analogo.
rem dal secondo livello ottengo il numero 31926 che rapprensenta il valore
rem (piccolo) per realizzare la divisione.
set /a my_gb=gb*1000/1000-(gb*1000/10000-gb*1000/31926)
echo %my_gb%
rem il valore trovato va bene per qualsiasi valore di gb , rappresenta solo il divisore.
Ho trovato comunque chi ci ha calcolato il PI (http://thedailywtf.com/Articles/Stupid-Coding-Tricks-A-Batch-of-Pi.aspx)(pi greco). Forse usando i metodi sopra citati.
Ma a questo punto, se il vbscript soddisfa certi requisiti , userò quello.
Ma mi serve una mano!
einstein1969
13-05-2011, 13:53
Praticamente il divisore e' piccolo e la divisione stessa e' semplice shift decimale. Il dividendo forse puo' subire la stessa sorte.
N/(1024*1024*1024)= (a meno di un errore) N-N/10+N/(3*10)-N/(4*100)+N/(2*1000)
e' una successione alternante.
Lo so, sembra arabo... :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.