Newsgroup: it.comp.lang.c++
Titolo: Limite di INT

Salve, sto mettendo per la prima volta le mani sul c++ e sto realizzando un 
banalissimo programmino che fatorializza dei numeri per testarne la 
primalità. Il tutto funziona perfettamente solo ho alcune cose che proprio 
non riesco a chiarire.
Come variabili utilizzo degli interi del tipo unsigned long int, che come da 
standard dovrebbero arrivare a rappresentare una cifra di 4,3 miliardi e 
spiccioli, il problema è che se metto il limite massimo il programma non 
funziona e non da il correto risultato fino che non scendo sotto i 3 mld. Da 
cosa può dipendere, ma oltretutto come può essere che se stampo il contenuto 
delle variabili a volte risulta negativo se vicino al limite?
Un secondo problema è il seguente, ho la necessita di raggiungere il più 
alto limite possibile che tipo diverso di dato posso utilizzare, senza usare 
metodi di primalità diversi dalla fattorizzazione?
Grazie dell'aiuto. 



Se posti un po' di codice sarebbe meglio :D
Comunque puoi far fermare la ricerca fino a che non raggiungi la
radice quadrata del numero che vuoi controllare.

 radice quadrata del numero che vuoi controllare.
SI tratta di un semplice ciclo for che controlla la parte decimale della 
divisione tra il numero dato e un variabile che va da 2 alla parte intera 
della radice quadrata del numero (gia avevo fermato il calcolo come mi 
consigli di fare), il problema č andare olte i 4,3 mld visto che non ci sono 
particolari problemi di attesa fino li mi piacerebbe spingermi oltre, quindi 
trovare un tipo di dato che me lo permatta.
grazie. 


[CUT] 
Ti ho fatto un piccolo esempio, č scritto di getto quindi perdonami
eventuali errori :D
#include <iostream>
#include <cmath>
using namespace std;
int main(){
	unsigned long n = 4000000000UL;
	bool isPrime = true;
	for(int i=2; i <= (unsigned long)ceil(sqrt(n)); ++i){
		if((n % i) == 0UL){
			isPrime = false;
			break;
		}
	}
	if(isPrime){
		cout << "Il numero " << n << " e' primo" << endl;
	}
	else{
		cout << "Il numero " << n << " non e' primo" << endl;
	}
	return 0;
}
C'č da dire che non ho capito bene il tuo riferimento qual'č:
unsigned int secondo lo standard arriva fino a 4Byte
mentr
unsigned long arriva fino a 8Byte (quindi supera di gran lunga i
4miliardi e rotti dell'unsigned int).
Poi dipende dal compilatore, nel mio (visual c++6) l'unsigned long
arriva a 4Byte. (ma nel visual 
studio.net
 credo arrivi ad essere
compatibile allo standard).
Se hai dei dubbi chiedi pure :)


Saro' un po' pedante come al solito, perdonatemi :)
<mattia Wall="yes" ansi="yes" pedantic="yes">
Allora, partiamo da una visione puramente 'standard'.
Il tipo 'unsigned long int' non arriva a 4,3 miliardi circa, da 
standard, bensi' ha un range che varia da 0 a ULONG_MAX (definito in 
<limits.h>). Il fatto che poi sul tuo sistema sia cosi', e' un altro 
discorso.
Il motivo per cui, quando arrivi verso il limite, diventi negativo, e' 
semplicemente dovuto a un undefined behaviour.
</mattia>
<mattia Wall="no" ansi="no" pedantic="yes">
Parliamo quindi del sistema su cui ti potresti trovare. Se un long e' 
rappresentato da 32 bit, con una codifica in complemento a due (che nel 
caso unsigned diventa banale), avrai un massimo di 4.294.967.296, e 
quindi il tuo discorso quadra. Mi pareva strano il discorso dei 3 mld, 
ma come ti e' gia' stato detto, senza codice sotto mano, e' difficile 
dire dove puo' stare il problema [1]... per lo meno prima di leggere il 
seguito. Tu hai detto che se esageri... va in negativo. Ora, per come e' 
definito il complemento a due, questo e' tipicamente segno di overflow, 
e in quel caso, si riparte dall'estremo negativo. Ma se tu avessi sempre 
usato _unsigned_ long int, non potresti proprio avere numeri negativi! 
Quindi, o stai usando anche dei signed long int (e in quel caso il tuo 
massimo scenderebbe a circa 2 miliardi), oppure li stai stampando come 
signed. In questo secondo caso, se non te ne sei accorto e' perche' non 
hai attivato tutti i warning del compilatore, e quindi ti dico: _fallo_. 
E' utile _sempre_ e _comunque_, a partire dal principiante, per arrivare 
all'esperto.
</mattia>
[1]: molto probabilmente il codice postato da Longanino e' corretto, 
pero' credo ti sarebbe piu' utile scoprire il perche' del tuo errore, 
piuttosto che avere codice funzionante ;)
-- 
Mat/tia Belletti             - Graduate student @ 
cs.unibo.it
ICQ: 33292311                - email: 
mbel...@cs.unibo.it
IRC: RedGlow                 - site(s): 
http://mbellett.web.cs.unibo.it/
Red...@jabber.linux.it/Gaim
 - Linux user 299762 @ machine 213003

 discorso.
dopo -pedantic c'è -stronzo vero? :(
#include <climits>
-- 
sbi


[CUT]
Anche il contatore è unsigned long :D 

Non mi pare che Mattia meriti insulti, con o senza smiley. Cerchiamo di
mantenere un minimo di educazione.
Ciao,
Nicola

 	for(int i=2; i <= (unsigned long)ceil(sqrt(n)); ++i){
Questo test viene di solito scritto come
i * i <= n
Per evitare che l'ottimizzazione diventi pessimizzazione a causa del
passaggio a numeri in virgola mobile e dell'utilizzo di una funzione
complessa come sqrt().
Ciao,
Nicola