Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Scomposizione in fattori primi

307 views
Skip to first unread message

Bruno Campanini

unread,
Jan 18, 2013, 8:33:09 AM1/18/13
to
Visto che i formulisti - Dio li abbia in gloria! - da qualche giorno
si tacciono, provo a richiedere a questo illustre consesso una
procedura VBA per la scomposizione di un numero in fattori primi.

Cercando di mettere un po' d'ordine nelle mie scartoffie mi sono
ritrovato fra le mani una procedura realizzata una decina d'anni
fa (Excel 2003) che oggi mi sembra ingenua, prolissa e farraginosa.

Qualcuno vorrebbe cimentarsi al riguardo?
Non ᅵ una gara e non vi sono premi.

Bruno


r

unread,
Jan 18, 2013, 8:54:38 AM1/18/13
to
Il giorno venerdì 18 gennaio 2013 14:33:09 UTC+1, Bruno Campanini ha scritto:
> Visto che i formulisti - Dio li abbia in gloria! - da qualche giorno si tacciono, provo a richiedere a questo illustre consesso una procedura VBA per la scomposizione di un numero in fattori primi. Cercando di mettere un po' d'ordine nelle mie scartoffie mi sono ritrovato fra le mani una procedura realizzata una decina d'anni fa (Excel 2003) che oggi mi sembra ingenua, prolissa e farraginosa. Qualcuno vorrebbe cimentarsi al riguardo? Non è una gara e non vi sono premi. Bruno

ma io avevo queste ... una è di Nur :-)

http://r-mensa.blogspot.it/2009/11/scomposizione-in-fattori-primi-vb.html

ciao
r

Andrea.9

unread,
Jan 18, 2013, 8:55:35 AM1/18/13
to
> Non è una gara e non vi sono premi.

... e ma allora :-p

questo e' un mio vecchissimo lavoretto
non e' in VBA e non so se puo' esserti utile
comunque:
http://docs.google.com/file/d/0B1kt3cvRBcZwZGVHOHlLUU1tTVU/edit
ciao
andrea

Bruno Campanini

unread,
Jan 18, 2013, 10:28:57 AM1/18/13
to
r pretended :
> Il giorno venerdᅵ 18 gennaio 2013 14:33:09 UTC+1, Bruno Campanini ha scritto:
>> Visto che i formulisti - Dio li abbia in gloria! - da qualche giorno si
>> tacciono, provo a richiedere a questo illustre consesso una procedura VBA
>> per la scomposizione di un numero in fattori primi. Cercando di mettere un
>> po' d'ordine nelle mie scartoffie mi sono ritrovato fra le mani una
>> procedura realizzata una decina d'anni fa (Excel 2003) che oggi mi sembra
>> ingenua, prolissa e farraginosa. Qualcuno vorrebbe cimentarsi al riguardo?
>> Non ᅵ una gara e non vi sono premi. Bruno
>
> ma io avevo queste ... una ᅵ di Nur :-)
>
> http://r-mensa.blogspot.it/2009/11/scomposizione-in-fattori-primi-vb.html
>
> ciao
> r

Sᅵ perᅵ io riesco a scomporre anche questo:
200 000 061 744 017 = 193 * 1 036 269 749 969
cioᅵ numeri <= 999 999 999 999 999 che ᅵ la massima
capacitᅵ numerica di Excel.

Bruno


r

unread,
Jan 18, 2013, 10:37:29 AM1/18/13
to
Il giorno venerdì 18 gennaio 2013 16:28:57 UTC+1, Bruno Campanini ha scritto:

beh il concetto non cambia ... solo bisogna avere delle funzioni MOD e Sqr che lavorano anche con nuemri maggiori dei long ...
ma perchè non riesco a leggere bene quello che scrivi?

r

unread,
Jan 18, 2013, 10:50:25 AM1/18/13
to
Il giorno venerdì 18 gennaio 2013 16:37:29 UTC+1, r ha scritto:

eccola:

Public Function Fattori_primi( _
ByVal N)

Dim F As Long
Dim T As Long
Dim R As Long
Dim S As String
'si basa sul principio che un numero
'e primo se non ha divisori > della
'sua radice
R = Sqr(N)
T = fMOD(N, 2 + 1)
F = 1
If N = 1 Then
S = N
Else
Do Until F > R
F = F + T
If fMOD(N, F) = 0 Then
S = S & F & "*"
N = N / F
F = F - T
R = Sqr(N)
End If
Loop
If N = 1 Then
S = Left(S, Len(S) - 1)
Else
S = S & N
End If
End If


ciao
r

Fattori_primi = S
'volendo una matrice sostituire con
'Fattori_primi = Split(S, "*")

End Function


Private Function fMOD(Numero1, Numero2)
fMOD = Numero1 - Numero2 * Int(Numero1 / Numero2)
End Function

Ammammata

unread,
Jan 18, 2013, 11:16:44 AM1/18/13
to
Il giorno Fri 18 Jan 2013 02:55:35p, *Andrea.9* inviava su
microsoft.public.it.office.excel il messaggio news:791f605b-9e99-4a9e-a1a1-
de3cb7...@googlegroups.com. Vediamo cosa scrisse:

>> Non � una gara e non vi sono premi.
provato con 11,111,111,111,113
mi da 13 x 854,700,854,701

un veloce controllo online:
854700854701 is not prime. It is divisible by 95003

quindi il foglio si ferma alla verifica dei numeri elencati a sinistra?
la posso allungare?

--
/-\ /\/\ /\/\ /-\ /\/\ /\/\ /-\ T /-\
-=- -=- -=- -=- -=- -=- -=- -=- - -=-
>>>>> http://www.bb2002.it :) <<<<<
........... [ al lavoro ] ...........

r

unread,
Jan 18, 2013, 12:02:06 PM1/18/13
to
Il giorno venerdì 18 gennaio 2013 16:50:25 UTC+1, r ha scritto:

è incredibile come i loop do fottono excel 2010 ... me ne devo ricordare ... grrr

r

unread,
Jan 18, 2013, 12:06:46 PM1/18/13
to
Il giorno venerdì 18 gennaio 2013 18:02:06 UTC+1, r ha scritto:
> Il giorno venerdì 18 gennaio 2013 16:50:25 UTC+1, r ha scritto: è incredibile come i loop do fottono excel 2010 ... me ne devo ricordare ... grrr

se inserisco queste nel modulo e provo nel foglio
=Fattori_primi(123456789)
excel 2010 non risponde più ... e il codice non si riesce a interrompere:

Public Function Fattori_primi( _
ByVal N)

Dim F
Dim T
Dim R
Fattori_primi = S
'volendo una matrice sostituire con
'Fattori_primi = Split(S, "*")
End Function


Private Function fMOD(Numero1, Numero2)
fMOD = Numero1 - Numero2 * Int(Numero1 / Numero2)
End Function
Show trimmed content

plinius

unread,
Jan 18, 2013, 1:52:31 PM1/18/13
to
Avevo una function per questo scopo, fatta qualche annetto fa.
-------------
Public Function Scom(N As Double) As String
Dim i As Double, es As Double, neg As Boolean
neg = (N < 0)
N = Abs(Int(N))
i = 2
Do While i <= Sqr(N)
es = 0
Do While Int(N / i) * i = N
es = es + 1
N = N / i
Loop
If es > 0 Then
Scom = Scom & " * " & i
If es > 1 Then Scom = Scom & "^" & es
End If
i = i + 2 + (i = 2)
Loop
If N > 1 Then Scom = Scom & " * " & N
Scom = Mid$(Scom, 4)
If neg Then Scom = "- " & Scom
If Len(Scom) = 0 Then Scom = N
End Function
---------------

Ciao,
E.

Bruno Campanini

unread,
Jan 18, 2013, 2:20:16 PM1/18/13
to
r formulated the question :
> Il giorno venerdᅵ 18 gennaio 2013 16:28:57 UTC+1, Bruno Campanini ha scritto:
>
> beh il concetto non cambia ... solo bisogna avere delle funzioni MOD e Sqr
> che lavorano anche con nuemri maggiori dei long ...
Se per concetto intendi l'algoritmo... beh allora cambia: io ho usato
SQR ma non MOD.

> ma perchᅵ non riesco a
> leggere bene quello che scrivi?
Non so che dirti.

Io ho problemi a leggere ;) e :) presenti nelle formule in italiano.
Mi appaiono tante faccine...

Bruno


Bruno Campanini

unread,
Jan 18, 2013, 2:24:29 PM1/18/13
to
Andrea.9 presented the following explanation :
>> Non ᅵ una gara e non vi sono premi.
Mi sembra un'idea originale ed elegante per risolvere il problema con
delle formule.

Bruno


Bruno Campanini

unread,
Jan 18, 2013, 2:51:14 PM1/18/13
to
plinius has brought this to us :
Adesso ci siamo!
=Scom(999999999999999) --> 3^3 * 31 * 37 * 41 * 271 * 2906161

Anch'io arrivo ai 15 nove...
perᅵ con un codice lungo 3 o 4 volte il tuo.

Bruno


paoloard

unread,
Jan 18, 2013, 4:09:42 PM1/18/13
to


"Bruno Campanini" ha scritto nel messaggio
news:50f9a175$0$40365$4faf...@reader1.news.tin.it...
Senza dimenticare il buon lavoro di Giovanna:
http://www.riolab.org/index.php?option=com_content&view=article&id=172&itemid=68

--
Ciao
paoloard
http://www.riolab.org/

r

unread,
Jan 18, 2013, 5:48:41 PM1/18/13
to
Il giorno venerdì 18 gennaio 2013 20:20:16 UTC+1, Bruno Campanini ha scritto:
> r formulated the question :
>
> > Il giorno venerdì 18 gennaio 2013 16:28:57 UTC+1, Bruno Campanini ha scritto:
>
> >
>
> > beh il concetto non cambia ... solo bisogna avere delle funzioni MOD e Sqr
>
> > che lavorano anche con nuemri maggiori dei long ...
>
> Se per concetto intendi l'algoritmo... beh allora cambia: io ho usato
>
> SQR ma non MOD.

e questo
Do While Int(N / i) * i = N
cos'è? non è do while n mod i = 0 ?


>
>
>
> > ma perchè non riesco a
>
> > leggere bene quello che scrivi?
>
> Non so che dirti.

non è colpa tua ... capita anche quando scrivono gli altri ... le accentate dovreste evitarle usando e'non fareste su quei casini

>
>
>
> Io ho problemi a leggere ;) e :) presenti nelle formule in italiano.

ho in serbo una sorpresa ... per il tuo compleanno :-)

>
> Mi appaiono tante faccine...

come questa :-)

>
>
>
> Bruno

ciao
r

Bruno Campanini

unread,
Jan 19, 2013, 5:36:11 AM1/19/13
to
r expressed precisely :
> Il giorno venerdᅵ 18 gennaio 2013 20:20:16 UTC+1, Bruno Campanini ha scritto:
>> r formulated the question :
>>
>>> Il giorno venerdᅵ 18 gennaio 2013 16:28:57 UTC+1, Bruno Campanini ha
>>> scritto:
>>>
>>
>>> beh il concetto non cambia ... solo bisogna avere delle funzioni MOD e Sqr
>>> che lavorano anche con nuemri maggiori dei long ...
>>
>> Se per concetto intendi l'algoritmo... beh allora cambia: io ho usato
>>
>> SQR ma non MOD.
>
> e questo
> Do While Int(N / i) * i = N
> cos'ᅵ? non ᅵ do while n mod i = 0 ?

Con chi te la prendi?

Bruno


Andrea.9

unread,
Jan 19, 2013, 5:39:20 AM1/19/13
to
> Mi sembra un'idea originale ed elegante per risolvere il problema con
> delle formule.

grazie, sicuramente miglorabile.
Andrea

Andrea.9

unread,
Jan 19, 2013, 5:43:56 AM1/19/13
to
> quindi il foglio si ferma alla verifica dei numeri elencati a sinistra?
> la posso allungare?

si, il numero primo piu' grande verificato e' 149 (che per uso scolastico era piu' che sufficiente)
si, si puo' allungare a piacimento replicando i riquadri dove di analizzano gruppi di numeri primi:
il primo riquadro verifica 2, 3, 5, 7, 11, 13, 17
il secondo riquadro verifica 19, 23, 29, 31, 37, 41, 43
e cosi' via
ciao
andrea

r

unread,
Jan 19, 2013, 6:42:35 AM1/19/13
to
Dico solo che usare mod o il so while com'è l'ha usato plinius è probabilmente anche te è la stessa cosa è non certo un algoritmo diverso

Ciao
r

plinius

unread,
Jan 19, 2013, 7:14:31 AM1/19/13
to
Il 19/01/2013 12:42, r ha scritto:
> Dico solo che usare mod o il so while com'� l'ha usato plinius � probabilmente anche te � la stessa cosa � non certo un algoritmo diverso
>
> Ciao
> r
>

Roberto,
� vero che l'algoritmo � identico, ma usando mod hai la possibilit� di
utilizzare numeri fino a 2147483647 (long), mentre eseguendo il calcolo
con variabili definite come double (o variant) ottieni risultati
corretti fino a 999999999999999.
Ciao,
E.

r

unread,
Jan 19, 2013, 7:47:52 AM1/19/13
to
Si lo so, ho proposto una funzione fMod ... Sostituendola a mod nella funzione per scomporre ... Sinceramente non ci vedevo nessuna difficoltà in più ne nessuna differenza sostanziale.
Ciao
r

Bruno Campanini

unread,
Jan 19, 2013, 10:08:25 AM1/19/13
to
r submitted this idea :
Treccani - Algoritmo:
In informatica, insieme di istruzioni che deve essere applicato per
eseguire un’elaborazione o risolvere un problema.

Per chi sa estrarre la radice quadrata:
SQR(2) = 1.41421

Per chi non sa estrarre la radice quadrata ma ha dimestichezza coi
logaritmi:
e^(1/2*ln[2]) = 1.41421
10^(1/2*log[10]) = 1.41421

Per chi non sa estrarre la radice quadrata né ha dimestichezza coi
logaritmi ma conosce la trigonometria:
1/(Pi/4 - (Pi/4)^3/3! + (Pi/4)^5/5! - (Pi/4)^7/
7! + (Pi/4)^9/9!) = 1.41421
1/(Sin(3/4 * Pi)) = 1.41421

Per chi ... sono tutti uguali!

Bruno


r

unread,
Jan 19, 2013, 10:41:28 AM1/19/13
to
della treccani hai la prima edizione?

ok io ho un ben più economico e recente dizionario Zanichelli 2000 ... accc una sfida impari! comunque... recita una definizione appena più sintetica ma a me più chiara:
"Procedimento per la risoluzione di un problema."

così per me il problema è la scomposizione in fattori primi e non la funzione resto.

a mod b
smod(a,b)
a-Int(a/b)*b
fanno lo stesso lavoro e lo fanno in modo indipendente e in modo identico con lo stesso algoritmo (beh mod non la vediamo ma la guida dice che fa quello)... e per me è la stessa cosa ... il problema comunque nel nostro caso è un altro.

Carine le varie versioni di SQR ... ma in quelle trigonometriche (non ci ho capito un h) dov'è la variabile 2?
:-)
ciao
r



Bruno Campanini

unread,
Jan 19, 2013, 11:10:41 AM1/19/13
to
After serious thinking plinius wrote :
Vorrei il tuo imprimatur su questa variante,
fatta a mio uso e consumo:
=============================================
Public Function Scom1(N) As String
If N < 0 Or Int(N) <> N Or N > 999999999999999# Then
Scom1 = "Risultato Indeterminato"
Exit Function
End If

Dim i As Integer, es As Integer

i = 2
Do While i <= Sqr(N)
es = 0
Do While Int(N / i) * i = N
es = es + 1
N = N / i
Loop
If es > 0 Then
Scom1 = Scom1 & " * " & i
If es > 1 Then Scom1 = Scom1 & "^" & es
End If
i = i + 2 + (i = 2)
Loop
If N > 1 Then Scom1 = Mid(Scom1 & " * " & N, 4)

End Function
============================================

Bruno


plinius

unread,
Jan 19, 2013, 11:41:15 AM1/19/13
to
Va benissimo, eccetto la dichiarazione della variabile i che, come
integer, rischia l'overflow
Prova a scomporre 999999961946176
Anche se l'overflow su es ᅵ praticamente impossibile, io dichiarerei sia
i che es come long.
Ciao,
Enrico

r

unread,
Jan 19, 2013, 12:33:29 PM1/19/13
to
> Anche se l'overflow su es è praticamente impossibile, io dichiarerei sia
>
> i che es come long.
>
> Ciao,
>
> Enrico

beh provata con 2147483648 restituisce
* 2^31

poi anche se il mio parere non è stato richiesto :-) io la funzione la lascerei variant (visto che gli passate un double) e gestirei questa riga
Scom1 = "Risultato Indeterminato"
con
Scom1 = CVErr(xlErrNA)

poi non capisco il limite di 999.999.999.999.999 ... mi sembra che la funzione possa accettare numeri fino a 4.611.686.014.132.420.000

bho
r

plinius

unread,
Jan 19, 2013, 2:20:32 PM1/19/13
to
>> Anche se l'overflow su es � praticamente impossibile, io dichiarerei sia
>>
>> i che es come long.
>>
>> Ciao,
>>
>> Enrico
>
> beh provata con 2147483648 restituisce
> * 2^31
>
> poi anche se il mio parere non � stato richiesto :-) io la funzione la lascerei variant (visto che gli passate un double) e gestirei questa riga
> Scom1 = "Risultato Indeterminato"
> con
> Scom1 = CVErr(xlErrNA)
>
> poi non capisco il limite di 999.999.999.999.999 ... mi sembra che la funzione possa accettare numeri fino a 4.611.686.014.132.420.000
>
> bho
> r
>

Per l'eliminazione dell'asterisco all'inizio, bisogna separare le due
istruzioni finali

If N > 1 Then Scom1 = Scom1 & " * " & N
Scom1 = Mid(Scom1, 4)

Quanto alla previsione di un limite numerico massimo, esclusione o meno
di negativi e numeri con decimali, tipo di messaggio di errore, penso si
tratti di preferenze personali non codificabili in astratto.

Ciao,
E.

r

unread,
Jan 19, 2013, 2:44:42 PM1/19/13
to
Il giorno sabato 19 gennaio 2013 20:20:32 UTC+1, plinius ha scritto:

> Quanto alla previsione di un limite numerico massimo, esclusione o meno
>
> di negativi e numeri con decimali, tipo di messaggio di errore, penso si
>
> tratti di preferenze personali non codificabili in astratto.

quell'altro ce l'ha la treccani ... ma tu te la sei mangiata :-)

comunque io ho ipotizzato questo (al di la delle preferenze personali) ... se usa come massimo valore 9 per 15 volte ... forse lo fa perchè excel ha una precisione di 15 cifre ... quindi lo vuole usare come udf ... quindi ... quindi i miei dubbi sono gli stessi di prima :-( ... meglio restituire un errore ... stupido fissare a 999999999999999 il massimo numero quando si può usare numeri maggiori .. excel ha una precisione di 15 caratteri ma gestisce numeri più grandi ...
e per questo numero
1.000.000.000.000.001 la funzione restituisce correttamente
7 * 11 * 13 * 211 * 241 * 2161 * 9091


ciao
r

plinius

unread,
Jan 19, 2013, 2:56:02 PM1/19/13
to
Il 19/01/2013 20:44, r ha scritto:
> Il giorno sabato 19 gennaio 2013 20:20:32 UTC+1, plinius ha scritto:
>
>> Quanto alla previsione di un limite numerico massimo, esclusione o meno
>>
>> di negativi e numeri con decimali, tipo di messaggio di errore, penso si
>>
>> tratti di preferenze personali non codificabili in astratto.
>
> quell'altro ce l'ha la treccani ... ma tu te la sei mangiata :-)
>
> comunque io ho ipotizzato questo (al di la delle preferenze personali) ... se usa come massimo valore 9 per 15 volte ... forse lo fa perch� excel ha una precisione di 15 cifre ... quindi lo vuole usare come udf ... quindi ... quindi i miei dubbi sono gli stessi di prima :-( ... meglio restituire un errore ... stupido fissare a 999999999999999 il massimo numero quando si pu� usare numeri maggiori .. excel ha una precisione di 15 caratteri ma gestisce numeri pi� grandi ...
> e per questo numero
> 1.000.000.000.000.001 la funzione restituisce correttamente
> 7 * 11 * 13 * 211 * 241 * 2161 * 9091
>
>
> ciao
> r
>

Ma � per questo che parlavo di preferenze personali.
Lavorando dal foglio con questa UDF hai qualche difficolt� a capire e
verificare bene che numero gli passi se vai oltri i 15 9.
D'altra parte � altrettanto vero che, per la maggior parte degli usi,
numeri da scomporre cos� alti difficilmente capitano

r

unread,
Jan 19, 2013, 3:10:34 PM1/19/13
to
Ma tu restituisci una stringa e poi quale altra funzione in excel ha come limite 99999999999999 solo perché non vedi bene i successivi? Forse l'idea più giusta sarebbe quella di far restituire una array coi numeri .... Anziché una stringa che ci fai nulla ...
Ciao
r

plinius

unread,
Jan 19, 2013, 3:49:23 PM1/19/13
to
Il 19/01/2013 21:10, r ha scritto:
> Ma tu restituisci una stringa e poi quale altra funzione in excel ha come limite 99999999999999 solo perch� non vedi bene i successivi? Forse l'idea pi� giusta sarebbe quella di far restituire una array coi numeri .... Anzich� una stringa che ci fai nulla ...
> Ciao
> r
>

La "scomposizione in fattori" ha, tipicamente, natura didattica.
Con la stringa che ci faccio? eheh la ricopio tale e quale sul quaderno
e frego la maestra... cos� impara a darci troppi compiti! :-))

Scherzi a parte, � ovvio che l'output lo si debba adattare alle esigenze
(che possono essere le pi� svariate).

Ciao,
E.

Bruno Campanini

unread,
Jan 20, 2013, 9:03:03 AM1/20/13
to
plinius explained :

> Va benissimo, eccetto la dichiarazione della variabile i che, come integer,
> rischia l'overflow
> Prova a scomporre 999999961946176
> Anche se l'overflow su es ᅵ praticamente impossibile, io dichiarerei sia i
> che es come long.

Sᅵ, hai ragione... rettifico!

Quindi Nihil obstat quominus imprimatur?

Apponi il tuo sigillo con la ceralacca.

Bruno


plinius

unread,
Jan 20, 2013, 10:24:13 AM1/20/13
to
Il 20/01/2013 15:03, Bruno Campanini ha scritto:
> plinius explained :
>
>> Va benissimo, eccetto la dichiarazione della variabile i che, come
>> integer, rischia l'overflow
>> Prova a scomporre 999999961946176
>> Anche se l'overflow su es è praticamente impossibile, io dichiarerei
>> sia i che es come long.
>
> Sì, hai ragione... rettifico!
>
> Quindi Nihil obstat quominus imprimatur?
>
> Apponi il tuo sigillo con la ceralacca.
>
> Bruno
>
>

Public Function Scom1(N) As String
If N < 0 Or Int(N) <> N Or N > 999999999999999# Then
Scom1 = "Risultato Indeterminato"
Exit Function
End If

Dim i As Long, es As Long

i = 2
Do While i <= Sqr(N)
es = 0
Do While Int(N / i) * i = N
es = es + 1
N = N / i
Loop
If es > 0 Then
Scom1 = Scom1 & " * " & i
If es > 1 Then Scom1 = Scom1 & "^" & es
End If
i = i + 2 + (i = 2)
Loop

' modificando anche qui per rimuovere i primi 3 caratteri *sempre*

If N > 1 Then Scom1 = Scom1 & " * " & N
Scom1 = Mid(Scom1, 4)

End Function

Ed ecco il sigillo! :-)
http://img541.imageshack.us/img541/751/senzatitolo1h.gif

Bruno Campanini

unread,
Jan 20, 2013, 1:11:15 PM1/20/13
to
plinius was thinking very hard :
Benissimo.
Cosa fatta e perfetta diviene norma cogente avente forza di legge.

Bruno


Bruno Campanini

unread,
Jan 20, 2013, 1:41:48 PM1/20/13
to
It happens that plinius formulated :

>> beh provata con 2147483648 restituisce
>> * 2^31
>>
>> poi anche se il mio parere non ᅵ stato richiesto :-) io la funzione la
>> lascerei variant (visto che gli passate un double) e gestirei questa riga
>> Scom1 = "Risultato Indeterminato"
>> con
>> Scom1 = CVErr(xlErrNA)
>>
>> poi non capisco il limite di 999.999.999.999.999 ... mi sembra che la
>> funzione possa accettare numeri fino a 4.611.686.014.132.420.000
>>
>> bho
>> r
>>
>
> Per l'eliminazione dell'asterisco all'inizio, bisogna separare le due
> istruzioni finali
>
> If N > 1 Then Scom1 = Scom1 & " * " & N
> Scom1 = Mid(Scom1, 4)
>
> Quanto alla previsione di un limite numerico massimo, esclusione o meno di
> negativi e numeri con decimali, tipo di messaggio di errore, penso si tratti
> di preferenze personali non codificabili in astratto.

Pensi male, non codificabili in astratto, CODIFICABILI IN CONCRETO!
I numeri primi sono solo numeri naturali (cioᅵ numeri interi e
positivi).
Contravvenendo a tale premessa si generano ambiguitᅵ quindi risultati
indeterminati.
La scomposizione di -8 potrebbe dare (-2)^3 ovvero 2^2 * (-2).
La scomposizione di 10.5 potrebbe dare 2 * 5.25 ovvero 2.625 * 2^2.

Bruno


Bruno Campanini

unread,
Jan 20, 2013, 1:48:27 PM1/20/13
to
r has brought this to us :
> Il giorno sabato 19 gennaio 2013 20:20:32 UTC+1, plinius ha scritto:
>
>> Quanto alla previsione di un limite numerico massimo, esclusione o meno
>>
>> di negativi e numeri con decimali, tipo di messaggio di errore, penso si
>>
>> tratti di preferenze personali non codificabili in astratto.
>
> quell'altro ce l'ha la treccani ... ma tu te la sei mangiata :-)

"Quell'altro" la Treccani ce l'ha in soffitta e non ha fatto certo 6
rami di scale per consultarla quando essa enciclopedia con annesso
dizionario delle lingua italiana (dal quale ha citato) ᅵ disponibile in
rete da diversi anni (http://www.treccani.it/).

Bruno


r

unread,
Jan 20, 2013, 2:04:25 PM1/20/13
to
Quindi plinius si è mangiato un computer?
:-)

r

unread,
Jan 20, 2013, 2:04:25 PM1/20/13
to

Bruno Campanini

unread,
Jan 20, 2013, 2:19:46 PM1/20/13
to
plinius formulated the question :

> Ma ᅵ per questo che parlavo di preferenze personali.
> Lavorando dal foglio con questa UDF hai qualche difficoltᅵ a capire e
> verificare bene che numero gli passi se vai oltri i 15 9.
> D'altra parte ᅵ altrettanto vero che, per la maggior parte degli usi, numeri
> da scomporre cosᅵ alti difficilmente capitano

Il massimo numero primo finora scoperto contiene 7 235 733 cifre e puᅵ
esprimersi con 2^(24 036 583)-1.

Mathematica v8.0 riesce a riprodurlo in 3431 pagine A4.

C'ᅵ un premio di 100 000 dollari (non ᅵ granchᅵ...) per la scoperta di
un numero primo con 10 milioni di cifre.

Bruno


plinius

unread,
Jan 20, 2013, 2:24:15 PM1/20/13
to
Il 20/01/2013 20:04, r ha scritto:
> Quindi plinius si � mangiato un computer?
> :-)
>

� vero s�, ma non l'ho digerito :-)

______________
P.S.:
Occasione da non perdere: vendonsi chip come nuovi, prezzi trattabili

r

unread,
Jan 20, 2013, 4:12:08 PM1/20/13
to
Plinius col mal di pancia ha scritto:

> È vero sì, ma non l'ho digerito :-)

sono sicuro che l'orso ha una grappa che ti fa digerire anche la scheda madre ... te lo deve no?
:-)
r

r

unread,
Jan 20, 2013, 4:20:22 PM1/20/13
to
Bruno Campanini ha pigramente scritto:

> "Quell'altro" la Treccani ce l'ha in soffitta e non ha fatto certo 6
>
> rami di scale per consultarla

accipicchia ... ma dove vivi sulla torre di un castello?
e comunque è uno spreco ... un sacrilegio tenerla in soffita!


> ... quando essa enciclopedia con annesso
>
> dizionario delle lingua italiana (dal quale ha citato) è disponibile in
>
> rete da diversi anni (http://www.treccani.it/).


per carità di dio ... questo non lo farò mai!
mi tengo il mio zanichelli ... lo sfoglio, lo scorro lo cullo ... lo annuso oh si ... il mio zanichelli ... per le parole c'è solo lui!
:-)

r

Bruno Campanini

unread,
Jan 20, 2013, 4:44:54 PM1/20/13
to
r was thinking very hard :
> Bruno Campanini ha pigramente scritto:
>
>> "Quell'altro" la Treccani ce l'ha in soffitta e non ha fatto certo 6
>>
>> rami di scale per consultarla
>
> accipicchia ... ma dove vivi sulla torre di un castello?
> e comunque ᅵ uno spreco ... un sacrilegio tenerla in soffita!

Mia moglie non la vuole in casa perchᅵ ᅵ troppo ingombrante, i miei
figli non l'hanno mai consultata, i miei nipoti... peggio che andar di
notte.
Comunque nel solaio ᅵ molto ben collocata, quindi si conserva bene.

Ora comunque ᅵ tutta on line consultabile gratuitamente assieme al
dizionario ed altro.

Bruno


r

unread,
Jan 22, 2013, 6:16:27 PM1/22/13
to
Il giorno domenica 20 gennaio 2013 16:24:13 UTC+1, plinius ha scritto:

con un piccolo accorgimento si può risparmiare quasi la metà del tempo nel caso di numeri primi molto alti ... ad esempio con 999999999999947# risparmia quasi 10 secondi (sulla mia cariola) impiegandone invece quasi 20 con la versione sigillata :-) ... si parla di una sola istruzione in più


Public Function Scom2(N) As String
If N < 0 Or Int(N) <> N Or N > 999999999999999# Then
Scom2 = "Risultato Indeterminato"
Exit Function
End If

Dim i As Long, es As Long, t As Long

i = 2
t = Sqr(N) + 1
Do While i <= t
es = 0
Do While Int(N / i) * i = N
es = es + 1
N = N / i
t = Sqr(N) + 1
Loop
If es > 0 Then
Scom2 = Scom2 & " * " & i
If es > 1 Then Scom2 = Scom2 & "^" & es
End If
i = i + 2 + (i = 2)
Loop

If N > 1 Then Scom2 = Scom2 & " * " & N
Scom2 = Mid(Scom2, 4)

End Function

saluti
r

plinius

unread,
Jan 23, 2013, 3:40:25 PM1/23/13
to
Un po' intricato questo ragionamento.

Dunque...
È indubbiamente una buona idea quella di ridurre il limite massimo del
Loop a t=Sqr(N) ogniqualvolta venga trovato un divisore perché,
ovviamente, questo consente una riduzione del tempo di esecuzione.
L'escamotage però non potrebbe dare nessun beneficio quando fossimo in
presenza di un numero primo e quindi, non essendoci divisori, la
function non ridimensiona mai t.
Mi sono chiesto allora come mai la scomposizione di 999999999999947 (che
è numero primo) fosse più veloce con la tua function e ho scoperto che
dipende dal fatto che ad ogni ciclo la mia function doveva ricalcolare
(pur restandone invariato il valore) Sqr(N)
Ho perciò inserito un t=Sqr(N) prima dell'inizio del Loop mettendo poi

Do While i <= t
...
Loop

invece di

Do While i <= Sqr(N)
...
Loop
e i tempi di esecuzione sono miracolosamente diventati uguali! :-)

Resta comunque validissima la modifica perché, quando ci sono divisori,
effettivamente dà i suoi benefici, anche se, in quella ipotesi, i tempi
si riducono moltissimo e le differenze di conseguenza diventano meno
vistose.
Per esempio la scomposizione di 999999999999934 = 2 * 499999999999967
(quindi con il solo divisore 2) avviene in un caso in 2,2 secondi e
nell'altro in 1,6 secondi. Ovviamente all'aumentare del numero di
divisori o del loro valore le differenze diventano quasi irrilevanti.

Quindi, concludendo, appongo volentieri anche il mio il sigillo a Scom2:
--------
Public Function Scom2(N) As String
If N < 0 Or Int(N) <> N Or N > 999999999999999# Then
Scom2 = "Risultato Indeterminato"
Exit Function
End If

Dim i As Long, es As Long, t As Long

i = 2
t = Sqr(N)
Do While i <= t
es = 0
Do While Int(N / i) * i = N
es = es + 1
N = N / i
t = Sqr(N)
Loop
If es > 0 Then
Scom2 = Scom2 & " * " & i
If es > 1 Then Scom2 = Scom2 & "^" & es
End If
i = i + 2 + (i = 2)
Loop

If N > 1 Then Scom2 = Scom2 & " * " & N
Scom2 = Mid(Scom2, 4)

End Function
--------

Ciao,
E.

r

unread,
Jan 23, 2013, 4:37:48 PM1/23/13
to
Il giorno mercoledì 23 gennaio 2013 21:40:25 UTC+1, plinius ha scritto:
> Il 23/01/2013 00:16, r ha scritto:
>
> > Il giorno domenica 20 gennaio 2013 16:24:13 UTC+1, plinius ha scritto:
>
> >
>
> > con un piccolo accorgimento si pu� risparmiare quasi la met� del tempo nel caso di numeri primi molto alti ... ad esempio con 999999999999947# risparmia quasi 10 secondi (sulla mia cariola) impiegandone invece quasi 20 con la versione sigillata :-) ... si parla di una sola istruzione in pi�
quale ragionamento?
il risparmio maggiore lo hai proprio coi numeri primi perchè il ricalcolo di Sqr(N) è completamente inutile essendo N costante

>
>
>
> Dunque...
>
> � indubbiamente una buona idea quella di ridurre il limite massimo del
>
> Loop a t=Sqr(N) ogniqualvolta venga trovato un divisore perch�,
>
> ovviamente, questo consente una riduzione del tempo di esecuzione.
>
> L'escamotage per� non potrebbe dare nessun beneficio quando fossimo in
>
> presenza di un numero primo e quindi, non essendoci divisori, la
>
> function non ridimensiona mai t.
>
> Mi sono chiesto allora come mai la scomposizione di 999999999999947 (che
>
> � numero primo) fosse pi� veloce con la tua function e ho scoperto che
>
> dipende dal fatto che ad ogni ciclo la mia function doveva ricalcolare
>
> (pur restandone invariato il valore) Sqr(N)

infatti ... e non ci vedo nulla di strano ... ad ogni loop deve verificare una condizione è normale che vengano ricalcolate le funzioni

>
> Ho perci� inserito un t=Sqr(N) prima dell'inizio del Loop mettendo poi

come ho fatto io appunto ...

>
>
>
> Do While i <= t
>
> ...
>
> Loop
>
>
>
> invece di
>
>
>
> Do While i <= Sqr(N)
>
> ...
>
> Loop
>
> e i tempi di esecuzione sono miracolosamente diventati uguali! :-)

ecco ... probabilmente non l'hai nemmeno guardata la mia ... perchè è esattamente quello che ho fatto ...

>
> Resta comunque validissima la modifica perch�, quando ci sono divisori,
>
> effettivamente d� i suoi benefici, anche se, in quella ipotesi, i tempi
>
> si riducono moltissimo e le differenze di conseguenza diventano meno
>
> vistose.
>
> Per esempio la scomposizione di 999999999999934 = 2 * 499999999999967
>
> (quindi con il solo divisore 2) avviene in un caso in 2,2 secondi e
>
> nell'altro in 1,6 secondi. Ovviamente all'aumentare del numero di
>
> divisori o del loro valore le differenze diventano quasi irrilevanti.
>

l'istruzione va spostata nel posto dove N viene modificata ... se ciò non avvenisse il tempo perso sarebbe di gran lunga superiore a quello appena guadagnato ... in questo caso il tempo che risparmiamo è evidente in particolare per numeri non primi


>
> Quindi, concludendo, appongo volentieri anche il mio il sigillo a Scom2:

accipicchia ... quanti formalismi :-)

saluti
r

r

unread,
Jan 23, 2013, 4:45:23 PM1/23/13
to
Il giorno mercoledì 23 gennaio 2013 22:37:48 UTC+1, r ha scritto:

ops ... l'ho chiamata "la mia" ... anche se è "la vostra" ... però in fin dei conti ... "la mia" (quella postata il 18 gennaio nel mio secondo intervento) faceva già le cose nel modo "giusto" ... mancava l'elevamento a potenza in caso di fattori primi ripetuti ... ma l'algoritmo era quello buono
:-)
r

plinius

unread,
Jan 23, 2013, 5:00:38 PM1/23/13
to
"Ragionamento intricato"
mi riferivo a quello che stavo per fare.

"Perché?"
Perché intendevo approvare la tua integrazione che è utile in generale
ma del tutto priva di effetti quando, invece, si volesse scomporre un
numero primo (che, invece, era proprio il tuo esempio). In quel caso il
risparmio di tempo aveva tutt'altra origine: l'inutile ripetizione
dell'estrazione della radice quadrata di N ad ogni ciclo.

Ciao,
E.

r

unread,
Jan 23, 2013, 5:18:45 PM1/23/13
to
Il giorno mercoledì 23 gennaio 2013 23:00:38 UTC+1, plinius ha scritto:

> "Perch�?"
>
> Perch� intendevo approvare la tua integrazione che � utile in generale
>
> ma del tutto priva di effetti quando, invece, si volesse scomporre un
>
> numero primo (che, invece, era proprio il tuo esempio). In quel caso il
>
> risparmio di tempo aveva tutt'altra origine: l'inutile ripetizione
>
> dell'estrazione della radice quadrata di N ad ogni ciclo.

scusa ma non ci siamo proprio ...
per mia integrazione cosa intendi?
questo:
N = N / i
>>>>>> t = Sqr(N) + 1

beh quella integrazione è completamente inutile se non sistemi prima questa:
>>>>>>t = Sqr(N) + 1
Do While i <= t
es = 0
Do While Int(N / i) * i = N
es = es + 1
....

le modifiche vanno prese insieme ... e il maggior risparmio lo si ottiene con i numeri primi perchè N rimane costante e non viene dunque mai ricalcolato ...

boh ... mi sembra un ottimo esempio di punti 2 e 3 del documento a te dedicato :-)

plinius

unread,
Jan 23, 2013, 5:41:52 PM1/23/13
to
Il 23/01/2013 23:18, r ha scritto:

> boh ... mi sembra un ottimo esempio di punti 2 e 3 del documento a te dedicato :-)
>


Non so perché non riusciamo a capirci se è tutto semplicissimo.
La tua function (copincollata dal post delle 00:16 di oggi) è questa:
-------------------------------
Public Function Scom2(N) As String
If N < 0 Or Int(N) <> N Or N > 999999999999999# Then
Scom2 = "Risultato Indeterminato"
Exit Function
End If

Dim i As Long, es As Long, t As Long <--- variabile t definita

i = 2
t = Sqr(N) + 1 <-- variabile t valorizzata
Do While i <= t
es = 0
Do While Int(N / i) * i = N
es = es + 1
N = N / i
t = Sqr(N) + 1 <-- variabile t aggiornata
Loop
If es > 0 Then
Scom2 = Scom2 & " * " & i
If es > 1 Then Scom2 = Scom2 & "^" & es
End If
i = i + 2 + (i = 2)
Loop

If N > 1 Then Scom2 = Scom2 & " * " & N
Scom2 = Mid(Scom2, 4)

End Function
-------------------------------
che differisce dalla mia per le sole tre cose evidenziate dai commenti.

A quelle modifiche mi sono riferito nei precedenti commenti e (salvo il
"+ 1" che è superfluo) ho approvato e condiviso.

Ho peraltro sottolineato che il vantaggio della modifica si ha solo
quando esistano divisori e non invece se passiamo alla function un
numero primo.

Infatti questa:
-------------------------------
Public Function Scom2(N) As String
If N < 0 Or Int(N) <> N Or N > 999999999999999# Then
Scom2 = "Risultato Indeterminato"
Exit Function
End If

Dim i As Long, es As Long, t As Long <--- variabile t definita

i = 2
t = Sqr(N) <-- variabile t valorizzata
Do While i <= t
es = 0
Do While Int(N / i) * i = N
es = es + 1
N = N / i
't = Sqr(N) + 1 <-- variabile t NON aggiornata
Loop
If es > 0 Then
Scom2 = Scom2 & " * " & i
If es > 1 Then Scom2 = Scom2 & "^" & es
End If
i = i + 2 + (i = 2)
Loop

If N > 1 Then Scom2 = Scom2 & " * " & N
Scom2 = Mid(Scom2, 4)

End Function
-------------------------------

impiega esattamente lo stesso tempo dell'altra se le passiamo un numero
primo (per esempio 999999999999947), mentre è più lenta quando vi siano
divisori.

Emh...l'inter che ha fatto domenica? :-)

Ciao,
E.

r

unread,
Jan 23, 2013, 6:11:31 PM1/23/13
to
Il giorno mercoledì 23 gennaio 2013 23:41:52 UTC+1, plinius ha scritto:

> impiega esattamente lo stesso tempo dell'altra se le passiamo un numero
>
> primo (per esempio 999999999999947), mentre � pi� lenta quando vi siano
>
> divisori.

ma per forza!


>
>
>
> Emh...l'inter che ha fatto domenica? :-)


buona questa grappa ... ne vuoi un bicchierino :-)
r

plinius

unread,
Jan 23, 2013, 7:04:03 PM1/23/13
to
Il 24/01/2013 00:11, r ha scritto:
> Il giorno mercoledě 23 gennaio 2013 23:41:52 UTC+1, plinius ha scritto:
>
>> impiega esattamente lo stesso tempo dell'altra se le passiamo un numero
>>
>> primo (per esempio 999999999999947), mentre ďż˝ piďż˝ lenta quando vi siano
>>
>> divisori.
>
> ma per forza!
>
>
>>
>>
>>
>> Emh...l'inter che ha fatto domenica? :-)
>
>
> buona questa grappa ... ne vuoi un bicchierino :-)
> r
>

Apperň!
ed io che sono ridotto cosě...
https://www.youtube.com/watch?v=iwsP-CP5aMQ
0 new messages