Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Range long unsigned int
Forum - C/C++ - Range long unsigned int

Avatar
Giarados (Ex-Member)
Pro


Messaggi: 69
Iscritto: 25/07/2010

Segnala al moderatore
Postato alle 4:53
Mercoledì, 08/12/2010
Il titolo non descrive assolutamente la domanda. Ma è l'unica cosa che mi viene in mente alle 4:40 del mattino :rofl:

Sto cercando di approssimare π alle prime 67 cifre decimali.

Non so quanto impiegherà il mio pc a terminare l'elaborazione, però nel frattempo mi è venuto un dubbio.
Codice sorgente - presumibilmente C/C++

  1. long unsigned int a,b;
  2. while(a+b<=8589934590)
  3. {
  4.  [...]
  5. }



Si può scrivere? Il compilatore mi avverte con un:
Codice sorgente - presumibilmente C/C++

  1. test.cpp:8: warning: integer constant is too large for ‘long’ type


Ultima modifica effettuata da Giarados il 08/12/2010 alle 5:03
PM
Avatar
Pitagora (Member)
Expert


Messaggi: 367
Iscritto: 12/06/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 11:03
Mercoledì, 08/12/2010
prova con un
Codice sorgente - presumibilmente C/C++

  1. long long unsigned int


Ultima modifica effettuata da Pitagora il 08/12/2010 alle 11:03
PM
Avatar
Giarados (Ex-Member)
Pro


Messaggi: 69
Iscritto: 25/07/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 12:01
Mercoledì, 08/12/2010
Con un bel po' di warnings me lo ha fatto passare ;)

Si ripropone per lo stesso problema: si può scrivere ciò che segue
Codice sorgente - presumibilmente Plain Text

  1. if(a+b == 36893488147419103230)
  2. {
  3.  [...]
  4. }



??

PM
Avatar
Pitagora (Member)
Expert


Messaggi: 367
Iscritto: 12/06/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 12:14
Mercoledì, 08/12/2010
presumo che il codice sia questo

Codice sorgente - presumibilmente C/C++

  1. long unsigned int a,b;
  2. while(a+b<=8589934590) { if(a+b == 36893488147419103230) { [...] } }



Il programma non entrerà mai nelle istruzioni associate a quell'if perchè 36893488147419103230 è maggiore di 8589934590 e quindi quando a+b sono maggiori di uno a 8589934590 (8589934591) il programma esce dal ciclo. Cmq non penso che ci sia un dato che riesca a contenere tutto questo numero: 36893488147419103230 Troppo grande. Ho persino problemi a leggerlo :rofl:

Ma che ci devi fare?

PM
Avatar
Giarados (Ex-Member)
Pro


Messaggi: 69
Iscritto: 25/07/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 12:25
Mercoledì, 08/12/2010
No, il codice sarebbe questo:
Codice sorgente - presumibilmente C++

  1. long long unsigned int a,b;
  2. while((a<=18446744073709551613) && (b<=18446744073709551613))
  3. {
  4.         if(a+b == 36893488147419103226)
  5.         {
  6.                 [...]
  7.         }
  8.  
  9.         a++;
  10.         b++;
  11. }



Il problema è che non ho modo di fare test! Ci starebbe giorni il mio pc ad incrementare a e b sino a quei valori.

Devo approssimare PI GRECO alle prime 67 cifre decimali :rofl:

Nota:
ho fatto un "esperimento" con due variabili char (tenendo conto degli opportuni range) e il tutto funge. Ora non so se lo stesso discorso sia valido per 36893488147419103226 e non ho modo di verificarlo ma se così fosse, su una macchina molto più potente di quella che uso, si potrebbe calcolare PI GRECO con una maggiore approssimazione utilizzando due contatori separati tali che (a+b)%2==1 (sempre).

Ultima modifica effettuata da Giarados il 08/12/2010 alle 12:38
PM
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 22:34
Giovedì, 09/12/2010
sapere il range di un tipo di dato è semplice, sapendo quanti byte occupa.
Fai un piccolo programma dove stampi sizeof( tipo_di_dato )
facciamo finta che il tuo ulong valga 4 byte
trasformiamo i byte in bit: 32 bit.
il range non è altro che 0-2^32-1. Non ne sono sicuro, ma penso che si possa dimostrare attraverso la serie geometrica.
nel caso sia signed, allora diventa -2^32/2 - 2^32/2-1
più semplicemente però, puoi includere <limits.h>
nel tuo caso avresto potuto fare
printf("range: [%d;%d]", 0, ULONG_MAX );
in C++ ancora più semplicemente numeric_limits< tipo >::max o ::min

PM
Avatar
Giarados (Ex-Member)
Pro


Messaggi: 69
Iscritto: 25/07/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 1:33
Venerdì, 10/12/2010
Non ci capiamo :rotfl:

Quello mi avete detto voi già lo so. Cerco di formulare meglio la domanda.

Avendo due variabili di tipo unsigned long long, mettiamo a e b:
Codice sorgente - presumibilmente C/C++

  1. unsigned long long a,b;



Io so che 0<=a>=18.446.744.073.709.551.615 e che b appartiene allo stesso intervallo di valori.

Poniamo K=18.446.744.073.709.551.615.

Posso valutare se
Codice sorgente - presumibilmente Plain Text

  1. a+b==2*K;


???

Posso utilizzare la somma di a e b come operando nei calcoli?

Oppure essendo tale numero fuori dal massimo range gestibile si genera qualche genere di errore?!

Io dai miei "esperimenti" ho desunto che è possibile farlo.

Applicazione pratica:
Devo calcolare le prime 68 cifre di pi_greco, so che:
pi_greco==4-(4/3)+(4/5)-(4/7)+(4/11)-(4/13)...
Per avere la migliore approssimazione possibile sulla mia macchina devo cercare di utilizzare tutte le cifre che il tipo dato con il più largo range (long double) per far ciò devo portare il 3 di 3.14159265[...] il più a sinistra possibile.
Ponendo dunque:
m=10000000000000000000000000000000000000000000000000000
ottengo che
m*pi_greco==m*4-(m*4/3)+(m*4/5)-(m*4/7)+(m*4/11)-(m*4/13)...

Avevo pensato, per ottenere una migliore approssimazione, di utilizzare due contatori separati ma non sapevo se era possibile effettuare una divisione per quei numeracci anche perchè fuori range. Adesso ho capito che si può fare.

Ma non ho concluso egualmente nulla: dividendo 4*m per 2*k ottengo un numero con più di venti cifre. :rotfl:

Anche se non mi alletta l'idea mi sa che dovrò dichiarare i due contatori come long double. :(

Ultima modifica effettuata da Giarados il 10/12/2010 alle 1:34
PM